ProgressDialog 的样式、标题和消息可以动态更改吗?

发布于 2024-11-01 10:01:35 字数 2598 浏览 1 评论 0原文


是否可以动态更改 PD 的样式、消息和标题(而不是从 UI 线程)?

我想做以下事情。第一次 PD 显示在 STYLE_SPINNER 中,因为它看起来像是无尽的进步,并显示通知用户应用程序正在查找 4 个内容的消息(某些更新 4 个实例)。当它发现某些东西时,它必须对其执行某些操作(安装它)。此时我想展示水平样式的 PD,因为它真正显示进度状态而不是旋转样式的 PD。

无论如何,我在尝试 PD.setMax() 时遇到了 NullPointerException。 PD 不为空,所以我无法了解发生了什么。

这是我的 Activity 类中的一个内部类:

    private class RestoreDBTask extends AsyncTask <Void, Void, String>
    {

        private ProgressDialog dialog;

        private Handler handler;

        @Override
        protected void onPreExecute()
        {

            this.dialog = new ProgressDialog(SplashActivity.this);
            this.dialog.setTitle(getString(R.string.progress_wait));
            this.dialog.requestWindowFeature(Window.FEATURE_PROGRESS);
//            this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            this.dialog.setProgress(0);
            this.dialog.show();

            handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    RestoreDBTask.this.dialog.hide();

                    switch (msg.what) {
                    case 0:{
                        RestoreDBTask.this.dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                        break; }
                    case 1: {
                        RestoreDBTask.this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                        break; }
                    case -1: {
                        RestoreDBTask.this.dialog.setMessage(getResources().getString(R.string.progress_db_installing));
                        break; }
                    case -2: {
                        RestoreDBTask.this.dialog.incrementProgressBy(1);
                        break; }
                    default: {
                        Log.i(APP_TAG,""+RestoreDBTask.this.dialog.getMax());
                        RestoreDBTask.this.dialog.setMax(msg.what); }
                    }

                    RestoreDBTask.this.dialog.show();
                }
            };
        }

        @Override
        protected String doInBackground(Void... params)
        {
            mDBHelper.initDB(dialog,handler);
            return "";
        }

        @Override
        protected void onPostExecute(String result)
        {
            dialog.dismiss();
            startNextActivity();
        }
    }

mDBHelper.initDB() 方法使用 handler.sendEmptyMessage() 调用,并带有一些 int 值,假设如果 msg.what>1 它是 PD 的最大值。
另外我不明白为什么 PD 的样式是 STYLE_SPINNER 时不显示进度状态?如果我将其更改为 STYLE_HORIZONTAL 则可以正常工作...

Is it possible to change PD's style, message and title on the fly (and not from UI thread)?

I want to do the following. Fist time PD shows in STYLE_SPINNER as it looks like endless progress and shows the message informing user that app is looking 4 something (some update 4 instance). And when it found that something it has to do something with it (install it). At this point i wanna show the HORIZONTAL styled PD as it really shows the progress state instead of spinner styled one.

Anyway I got NullPointerException while trying to PD.setMax(). PD isn't null so I can't get what's going on.

This is an inner class in my Activity class:

    private class RestoreDBTask extends AsyncTask <Void, Void, String>
    {

        private ProgressDialog dialog;

        private Handler handler;

        @Override
        protected void onPreExecute()
        {

            this.dialog = new ProgressDialog(SplashActivity.this);
            this.dialog.setTitle(getString(R.string.progress_wait));
            this.dialog.requestWindowFeature(Window.FEATURE_PROGRESS);
//            this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            this.dialog.setProgress(0);
            this.dialog.show();

            handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    RestoreDBTask.this.dialog.hide();

                    switch (msg.what) {
                    case 0:{
                        RestoreDBTask.this.dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                        break; }
                    case 1: {
                        RestoreDBTask.this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                        break; }
                    case -1: {
                        RestoreDBTask.this.dialog.setMessage(getResources().getString(R.string.progress_db_installing));
                        break; }
                    case -2: {
                        RestoreDBTask.this.dialog.incrementProgressBy(1);
                        break; }
                    default: {
                        Log.i(APP_TAG,""+RestoreDBTask.this.dialog.getMax());
                        RestoreDBTask.this.dialog.setMax(msg.what); }
                    }

                    RestoreDBTask.this.dialog.show();
                }
            };
        }

        @Override
        protected String doInBackground(Void... params)
        {
            mDBHelper.initDB(dialog,handler);
            return "";
        }

        @Override
        protected void onPostExecute(String result)
        {
            dialog.dismiss();
            startNextActivity();
        }
    }

the mDBHelper.initDB() method uses handler.sendEmptyMessage() calls with some int values assuming if msg.what>1 it is Max value for PD.
Also I can't figure out why PD doesn't show the progress state if it's style is STYLE_SPINNER? If i change it to STYLE_HORIZONTAL it works ok...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蒲公英的约定 2024-11-08 10:01:35

我遇到过在执行 show() 方法后无法更改 PD 的样式(但仅限 b4),因为如果应用程序在此之后尝试调用 setMax()/setProgress()/increment 等方法,则会导致 NullPointerException。此外,即使使用 hide()->change style->show() 模式,PD 的样式在视觉上也根本不会改变。

我的解决方案是在更改其样式时重新创建 PD (从旋转器到条或顺时针)。但问题是 - 我无法获取现有 PD 的标题和消息并将其复制到新 PD,因为相应的方法(getTitle/getMessage)不存在,这是愚蠢的原因,setter 方法确实存在,因此它破坏了 Java bean 规则。他们为什么不提供吸气剂?

与 PD 的风格不同,它的标题和消息可以随时更改。

I've encountered that PD's style couldn't be changed after show() method was executed (but only b4) because is causes a NullPointerException if app tries to call setMax()/setProgress()/increment etc. methods after that. Moreover PD's style doesn't change visually at all even in case of using hide()->change style->show() schema.

My solution is to recreate PD in case of changing it's style (from spinner to bar or clockwise). But the problem is - I cant get Title and Message of existing PD to copy it to the new PD due to corresponding methods (getTitle/getMessage) doesn't exists and thats stupid cause setter methods do exists so it breaks Java beans rules. Why didn't they provide getters?

Unlike PD's style it's title and message could be changed on the fly.

帅冕 2024-11-08 10:01:35

是否可以动态更改 PD 的样式、消息和标题(而不是从 UI 线程)?

无法在另一个Thread 中更新 UI 内容。您应该做的是重写 onProgressUpdate() ,这样您就可以在 doInBackground() 中的代码仍在处理时更新 UI。

示例代码:

@Override
protected String doInBackground(Void... params) {

    // Use publishProgress() to update the UI thread from
    // a working background process.

    // If you have the initDB in another class you should probably
    // pass your RestoreDBTask instance to your initDB and call the instance's
    // makeProgress() method to successfully use publishProgress().
    mDBHelper.initDB(dialog, handler, this);
    return "";
}

@Override
protected void onProgressUpdate(Integer... params) {
    // If you gradually should update the ProgressDialog you probably need
    // an Integer value as argument in this method.

    // Update the ProgressDialog here.
}

public void makeProgress(Integer... params) {
    publishProgress(params);
}

Is it possible to change PD's style, message and title on the fly (and not from UI thread)?

It's not possible to update UI stuff in another Thread. What you should do is to override onProgressUpdate() and there you can update the UI while the code in doInBackground() still processing.

Sample code:

@Override
protected String doInBackground(Void... params) {

    // Use publishProgress() to update the UI thread from
    // a working background process.

    // If you have the initDB in another class you should probably
    // pass your RestoreDBTask instance to your initDB and call the instance's
    // makeProgress() method to successfully use publishProgress().
    mDBHelper.initDB(dialog, handler, this);
    return "";
}

@Override
protected void onProgressUpdate(Integer... params) {
    // If you gradually should update the ProgressDialog you probably need
    // an Integer value as argument in this method.

    // Update the ProgressDialog here.
}

public void makeProgress(Integer... params) {
    publishProgress(params);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文