【问题标题】:Best way to show a loading/progress indicator?显示加载/进度指示器的最佳方式?
【发布时间】:2012-10-02 06:00:03
【问题描述】:

在应用等待服务器响应时显示加载微调器的最佳方式是什么?

这可以通过编程方式完成吗?这样我就不用在xml文件中添加加载微调器了?

【问题讨论】:

    标签: android android-spinner


    【解决方案1】:

    ProgressDialog 已从 Android Oreo 中弃用。请改用ProgressBar

    ProgressDialog progress = new ProgressDialog(this);
    progress.setTitle("Loading");
    progress.setMessage("Wait while loading...");
    progress.setCancelable(false); // disable dismiss by tapping outside of the dialog
    progress.show();
    // To dismiss the dialog
    progress.dismiss();
    

    ProgressDialog.show(this, "Loading", "Wait while loading...");
    

    Read more here.

    顺便说一下,Spinner 在 Android 中有不同的含义。 (就像 HTML 中的选择下拉菜单)

    【讨论】:

    • 来自 Android 开发者网站:STYLE_SPINNER 创建一个带有圆形旋转进度条的 ProgressDialog。
    • 这行得通,但是当我测试它时,我可以通过触摸它外面的屏幕或按 Back 按钮来关闭对话框。我通过添加对progress.setCancelable(false); 的调用来解决此问题。
    • 感谢底部评论。我要疯了,因为我试图让“微调器”工作一个小时。
    • ProgressDialog 在 Android O 中已弃用 developer.android.com/reference/android/app/ProgressDialog.html
    • @IvanSemkin 关于替代品的任何建议?
    【解决方案2】:

    ProgressDialog 自 API 级别 26 起已弃用 https://developer.android.com/reference/android/app/ProgressDialog.html

    我在布局中包含一个 ProgressBar

       <ProgressBar
            android:layout_weight="1"
            android:id="@+id/progressBar_cyclic"
            android:visibility="gone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:minHeight="40dp"
            android:minWidth="40dp" />
    

    并将其可见性更改为 .GON​​E | .VISIBLE 取决于用例。

        progressBar_cyclic.visibility = View.VISIBLE
    

    【讨论】:

    • 不确定,但是progressBar 在使其不可见后是否总是在后台运行(只是从UI 中隐藏)?
    • @Shambhu 如果将其设置为View.GONE,则它根本不会在 UI 中呈现,并且对性能没有负面影响。 View.INVISIBLE 就像让它透明,但它在 UI 中,因此性能更差。
    【解决方案3】:

    使用ProgressDialog

    ProgressDialog.show(Context context, CharSequence title, CharSequence message);
    

    然而,这在今天(2013 年)被认为是一种反模式:http://www.youtube.com/watch?v=pEGWcMTxs3I

    【讨论】:

    • @artworkadshi 那么这方面的哪些方面被认为是不好的——接受的答案是相同反模式的例子吗?建议做什么呢?链接到关于多个用户体验问题的非现场视频并不能真正改善这个答案。
    • ProgressDialog 在 Android O 中已弃用 developer.android.com/reference/android/app/ProgressDialog.html
    【解决方案4】:

    实际上,如果您正在等待来自服务器的响应,它应该以编程方式完成。您可以创建一个进度对话框并将其关闭,但这又不是“android 方式”。

    目前推荐的方法是使用 DialogFragment

    public class MySpinnerDialog extends DialogFragment {
    
        public MySpinnerDialog() {
            // use empty constructors. If something is needed use onCreate's
        }
    
        @Override
        public Dialog onCreateDialog(final Bundle savedInstanceState) {
    
            _dialog = new ProgressDialog(getActivity());
            this.setStyle(STYLE_NO_TITLE, getTheme()); // You can use styles or inflate a view
            _dialog.setMessage("Spinning.."); // set your messages if not inflated from XML
    
            _dialog.setCancelable(false);  
    
            return _dialog;
        }
    }
    

    然后在您的活动中设置片段管理器并在等待服务器开始后显示对话框:

    FragmentManager fm = getSupportFragmentManager();
    MySpinnerDialog myInstance = new MySpinnerDialog();
    }
    myInstance.show(fm, "some_tag");
    

    一旦您的服务器响应完成,您将关闭它:

    myInstance.dismiss()
    

    请记住,progressdialog 是一个微调器或进度条,具体取决于属性,请参阅api guide 了解更多信息

    【讨论】:

    • ProgressDialog.show(上下文上下文,CharSequence 标题,CharSequence 消息);将标题参数作为空字符串传递会删除标题:ProgressDialog.show(context, "", "Loading..");
    • 很好的例子,尽管我仍然可以使用后退按钮。我认为这是因为您的变量 dlgAlert (顺便说一句,它来自哪里?:))。无论如何 - 由于您正在扩展 dialogfragment,您只需调用 setCancelable(false) 即可。
    • 在服务器返回响应的不确定时间提交片段事务似乎不是万无一失的。例如,当响应返回时,承载该片段的活动可能处于错误状态。有什么解决办法吗?
    • 确保您导入的是 android.support.v4.app.DialogFragment 而不是 android.app.DialogFragment,否则您无法使用 getSupportFragmentManager(请参阅stackoverflow.com/questions/27514338/…
    • ProgressDialog 在 Android O 中已弃用 developer.android.com/reference/android/app/ProgressDialog.html
    【解决方案5】:

    我就是这样做的,这样一次只能打开一个进度对话框。根据 Suraj Bajaj 的回答

    private ProgressDialog progress;
    
    
    
    public void showLoadingDialog() {
    
        if (progress == null) {
            progress = new ProgressDialog(this);
            progress.setTitle(getString(R.string.loading_title));
            progress.setMessage(getString(R.string.loading_message));
        }
        progress.show();
    }
    
    public void dismissLoadingDialog() {
    
        if (progress != null && progress.isShowing()) {
            progress.dismiss();
        }
    }
    

    我也不得不使用

    protected void onResume() {
        dismissLoadingDialog();
        super.onResume();
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-10
    • 2017-01-11
    • 2016-09-27
    • 2011-09-29
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多