【问题标题】:Improving user experience with toggling on/off over 300 CheckBoxes通过切换超过 300 个复选框来改善用户体验
【发布时间】:2019-01-21 14:02:09
【问题描述】:

我制作了一个简单的烹饪应用程序,用户可以在其中选择多个项目并获取包含所选成分的食谱列表。有两种选择成分的模式:标签和复选框。在第二种模式中,您可以输入您想要的成分数量并点击“随机化”按钮或只需按“选择/取消选择所有成分”按钮。问题始于超过 300 个(具体为 386 个)的复选框数量。代码运行正常,但GUI冻结时间过长。

所以,我得到了HashMap <String/CheckBox> checkBoxHashMap,其中键是复选框的标记。要全选(与取消全选相同,但使用 false 值)我使用的是以下代码:

for (CheckBox chkBox: checkBoxHashMap.values()) {
        chkBox.setChecked(true);
    }

我尝试使用的内容: 1) 使用ProgressBar。问题是,ProgressBar 的动画在所有CheckBoxes 的选择/取消选择期间被冻结。另外,大多数时候ProgressBar 甚至都没有出现(在选择了所有CheckBoxes 之后,我隐藏了ProgressBar; 2) 在调用chkBox.setChecked(true); 后立即使用chkBox.jumpDrawablesToCurrentState();,这是我能获得的最好的性能,但它仍然滞后并且不满意。

我想要什么: 我想让它更加用户友好(我相信,冻结的 GUI 根本不是用户友好的)。我想实现软切换所有复选框(链状动画)或其他东西,如禁用动画并在所有CheckBoxes 改变它们的状态并将它们重新绘制在一起之后重新启用它。

有没有办法实现这样的目标?

【问题讨论】:

    标签: java android performance checkbox


    【解决方案1】:

    老实说,如果我是你,我会使用 RecyclerView 来处理这种情况。

    在屏幕上同时显示 300 个项目绝不是一个好主意:用户不可能同时需要所有项目,系统也不应该处理这种负载。

    这个概念是回收视图,这意味着一旦视图变得不可见,它所需的资源就会被释放,并且可以重新用于另一个数据单元。

    我做了一个关于 RecyclerView 的介绍 article 有很多例子,看看

    在您的特定情况下,只需为复选框制作适当的数据集并异步更改它,在 UI 线程上使用此操作的结果来更新 RCV(与您现在的操作相比,这是一个非常轻量级的操作)

    【讨论】:

    • 这是正确的答案。您不必使用 RecyclerView,但您肯定需要一些不会尝试在屏幕外渲染内容的父级。
    • 绝对是正确的答案。老实说,我想到了 RecyclerView,但因为我忘记了它的主要功能——只重绘可见视图而放弃了这个想法。感谢您的帮助!
    【解决方案2】:

    setChecked 操作非常昂贵,以至于在前台线程中的大量对象上执行它会导致 UI 冻结,因为该工作耗时太长,并且应用无法在刷新周期内完成 UI 更新。您应该在后台执行昂贵的操作:

    new AsyncTask() {
        @Override
        protected Object doInBackground(Object[] objects) {
            for (CheckBox chkBox: checkBoxHashMap.values()) {
                chkBox.setChecked(true);
            }
            return null;
        }
    }.execute();
    

    【讨论】:

    • 这个解决方案有问题:Only the original thread that created a view hierarchy can touch its views.
    猜你喜欢
    • 2019-03-14
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    相关资源
    最近更新 更多