【问题标题】:ListView: setvisibility() forces refreshing all the rowsListView: setvisibility() 强制刷新所有行
【发布时间】:2018-09-30 03:37:44
【问题描述】:

我有一个具有不同布局的行的 ListView。所以我使用的是ViewHolder的模式。

如果用户单击一行,则必须显示/隐藏同一行的一个子布局。

        viewHolder.btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = (int) v.getTag();
                Log.d(TAG, "Line in position " + position + " clicked");

                if (!checkBoxSendChoice[position]) {
                    checkBoxSendChoice[position] = true;
                    viewHolder.layout_choice.setVisibility(View.VISIBLE);
                } else {
                    checkBoxSendChoice[position] = false;
                    viewHolder.layout_choice.setVisibility(View.GONE);
                }
            }
        });

但是我注意到,由于 setVisibility(),整个 ListView 都被刷新了(所有行都多次调用 getView)。如果我注释掉这两个 setVisibility() 指令,ListView 将不再刷新。

是否可以优化并避免刷新ListView中的所有视图?

【问题讨论】:

    标签: java android listview visibility android-viewholder


    【解决方案1】:

    我认为有更好的方法来做到这一点。而不是直接编辑视图,您应该在列表项中有一个Boolean isVisible 并更改它,然后通知适配器项目已更改。这将使持有者重新绑定到该项目。在持有人的绑定函数中,您可以设置视图的可见性取决于布尔值。这是一个粗略的例子(半伪代码):

    List<MyItem> items;
    
    viewHolder.btn1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int position = (int) v.getTag();
            Log.d(TAG, "Line in position " + position + " clicked");
    
            checkBoxSendChoice[position] != checkBoxSendChoice[position];
            items.get(position).isVisible = heckBoxSendChoice[position];
    
            adapter.notifyItemRangeChanged(position, 1);
        }
    });
    
    class MyItem {
        boolean isVisible = true;
    }
    
    class holder {
        View layout_choice;
    
        private void onBind(MyItem item) {
            if (item.isVisible) {
                layout_choice.setVisibility(View.VISIBLE);
            } else {
                layout_choice.setVisibility(View. GONE);
            }
        }
    }
    

    通过使用 notifyItemRangeChanged 通知适配器,适配器将知道哪些项目已更新,因此只会刷新它们。 如果您愿意,我很乐意使用经过测试的示例来编辑我的答案。希望这会有所帮助!

    【讨论】:

    • 首先,我不明白为什么在 onClick() 回调中设置一行元素的可见性会强制重绘所有行。在我看来,显示/隐藏行的一部分最直观的方式。但是我不明白你不是立即的解决方案。请问,你能提供一个完整的例子吗?您的布尔值项目列表是我的 checkBoxSendChoice[] 数组(实际上是一个布尔值)。
    猜你喜欢
    • 1970-01-01
    • 2013-10-08
    • 2018-12-16
    • 1970-01-01
    • 2021-10-10
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多