ListView: setvisibility() 强制刷新所有行

Posted

技术标签:

【中文标题】ListView: setvisibility() 强制刷新所有行【英文标题】:ListView: setvisibility() forces refreshing all the rows 【发布时间】: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中的所有视图?

【问题讨论】:

【参考方案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[] 数组(实际上是一个布尔值)。

以上是关于ListView: setvisibility() 强制刷新所有行的主要内容,如果未能解决你的问题,请参考以下文章

布局的动态 id 的 setVisibility true

ListView 中的可见性消失

ListView中动态显示隐藏HeaderView和FooterView

android listview中如何将获取来的数据添加至listview尾部

Android:为什么setVisibility(View.GONE);或setVisibility(View.INVISIBLE);不工作

在视图动画时调用 setVisibility