我制作了一个简单的烹饪应用程序,用户可以在其中选择多个项目,并获得包含所选食材的食谱列表。有两种选择成分的模式:按标签和按复选框。在第二种模式下,您可以输入所需成分的数量,然后单击“随机化”按钮,或仅按“选择/取消选择所有成分”按钮。问题开始于超过300个复选框(具体来说是386个)的复选框。代码工作正常,但是GUI保持冻结的时间太大。
因此,我得到了HashMap <String/CheckBox> checkBoxHashMap
,其中key是复选框的标签。要选择全部(与取消全部选择相同,但值为false
),我正在使用以下代码:
for (CheckBox chkBox: checkBoxHashMap.values()) {
chkBox.setChecked(true);
}
我尝试使用的是:
1)使用ProgressBar
。问题在于,ProgressBar
的动画在所有CheckBox
的选择/取消选择期间被冻结。另外,大多数时间ProgressBar
甚至都没有露面(在选择了所有ProgressBar
个之后,我把CheckBox
隐藏了;
2)在致电chkBox.jumpDrawablesToCurrentState();
之后立即使用chkBox.setChecked(true);
,这是我可以获得的最好成绩,但是仍然落后并且不满意我。
我想要什么:
我想使其更加用户友好(我相信冻结的GUI根本不是用户友好的)。我想实现软切换开/关所有CheckBox(类似链的动画)或其他诸如禁用动画并在所有CheckBox
es更改其状态并重新绘制它们之后重新启用动画的功能。
有没有办法实现这样的目标?
答案 0 :(得分:4)
老实说,如果我是你,我会使用RecyclerView
来处理这种情况。
在屏幕上同时显示300个项目绝不是一个好主意:用户不可能一次需要所有这些项目,系统也不应该处理此类负载。
概念是回收视图,这意味着一旦视图变得不可见,便会丢弃视图所需的资源,并可将其重新用于另一个数据单元。
我通过许多示例对RecyclerView进行了介绍article,请看
在您的特定情况下,只需为复选框设置适当的数据集并异步更改它,就可以在UI线程上使用此操作的结果来更新RCV(与您现在拥有的操作相比,这是一个非常轻量级的操作)
答案 1 :(得分:0)
setChecked操作非常昂贵,以至于在前台线程中的大量对象上执行该操作会导致UI冻结,因为工作时间太长,并且应用程序无法在刷新周期内完成UI的更新。您应该在后台执行昂贵的操作:
new AsyncTask() {
@Override
protected Object doInBackground(Object[] objects) {
for (CheckBox chkBox: checkBoxHashMap.values()) {
chkBox.setChecked(true);
}
return null;
}
}.execute();