RecyclerView复用ViewHolder导致控件有时显示有时消失问题

本篇内容仅用来记录开发过程,提醒自己。本人目前实习,刚结束安卓三个月,能力有限,如有错误,欢迎指出。

	在开发项目过程中,使用Recycler有需求需要在不同情况下显示不同的控件。当时并不知道ViewHolder会被复用,并且只针对不同情况进行控件隐藏,但是并未显示,导致复用该ViewHolder的item的某些控件不显示。在空闲时间自己写了一个Demo进行了验证。
	以下是Demo内容
	首先写一个最简单的RecycleView例子

MainActivity.java

public class MainActivity extends AppCompatActivity {
    @BindView(R.id.rv_demo)
    RecyclerView rvDemo;
    @BindView(R.id.btn_demo)
    Button btnDemo;

    private AdapterDemo adapterDemo;
    private Set viewHoderSet = new HashSet<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        List list = new ArrayList<>();
        list.add("0");
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        list.add("6");
        list.add("7");
        list.add("8");
        list.add("9");
        list.add("10");
        list.add("11");
        list.add("12");
        list.add("13");
        list.add("14");
        list.add("15");
        list.add("16");
        list.add("17");
        list.add("18");
        list.add("19");
        list.add("20");
        list.add("21");
        list.add("22");
        adapterDemo = new AdapterDemo(list, this);
        rvDemo.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        rvDemo.setAdapter(adapterDemo);

    }

    @OnClick(R.id.btn_demo)
    public void showViewHolder(){
        Iterator iterator = viewHoderSet.iterator();
        Log.i("个数", "viewHolder " + viewHoderSet.size());
        while (iterator.hasNext()){
            Log.i("viewHolder", iterator.next().toString());
        }
    }

    public class AdapterDemo extends RecyclerView.Adapter {
        private List demoList;
        private Context mContext;
        public AdapterDemo(List demoList, Context mContext) {
            this.demoList = demoList;
            this.mContext = mContext;
        }
        @Override
        public MyViewHoder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(mContext).inflate(R.layout.adapter_item, parent, false);
            return new MyViewHoder(v);
        }
        @Override
        public void onBindViewHolder(MyViewHoder holder, int position) {
            Log.e("测试", holder.toString() + " -- " + position);
            viewHoderSet.add(holder);
            if (position % 5 == 0)
                holder.tv_demo.setVisibility(View.GONE);
            else
                holder.tv_demo.setText(demoList.get(position));
        }
        @Override
        public int getItemCount() {
            return demoList.size();
        }
        class MyViewHoder extends RecyclerView.ViewHolder {
            ImageView iv_demo;
            TextView tv_demo;

            public MyViewHoder(View itemView) {
                super(itemView);
                iv_demo = itemView.findViewById(R.id.iv_demo);
                tv_demo = itemView.findViewById(R.id.tv_demo);
            }
        }
    }
}

MainActivity布局


    

RecycleView item 布局



    
    

实现的功能很简单,就是在页面上显示如下图的页面,其中把position是5的倍数的ViewHolder的tv_Demo 控件隐藏掉。按钮的功能是为了能清除的看到生成了几个ViewHolder。效果如图

RecyclerView复用ViewHolder导致控件有时显示有时消失问题_第1张图片

打印的Log:

RecyclerView复用ViewHolder导致控件有时显示有时消失问题_第2张图片

目前为止一切正常,可以看到确实position为5的倍数的ViewHolder的TextView确实被隐藏掉了。然后向下滑动到最底层。
效果如图:

RecyclerView复用ViewHolder导致控件有时显示有时消失问题_第3张图片

这里发现了postion为17和22的TextView也不见了,查看一下Log

RecyclerView复用ViewHolder导致控件有时显示有时消失问题_第4张图片

发现第17和第22的ViewHolder是复用第0个和第5个的ViewHolder,而在代码处理中,第0个和第5个的ViewHolder中的TextView我们给隐藏掉了。
关键代码如下:

RecyclerView复用ViewHolder导致控件有时显示有时消失问题_第5张图片

当执行到postion = 17 的时候,判断一下postion不是5的倍数,执行赋值操作,但是这个ViewHolder在postion等于5的时候TextView被隐藏了,而且这里并没有在赋值操作时设置TextView可见,导致虽然赋值了,但是不可见也没用。想要改正也很简单,加一句可见语句就行。

RecyclerView复用ViewHolder导致控件有时显示有时消失问题_第6张图片

另外在打印ViewHolder生成个数的时候发现总共生成了12个ViewHolder,然而我们又23个item。(不同设备生成的可能不一样,我这里用PAD生成12个,用手机生成10个,另外如果加上可见语句则PAD生成11个)

RecyclerView复用ViewHolder导致控件有时显示有时消失问题_第7张图片

因为这个问题导致在项目开发时利用RecycleView展示的时候数据时有时无,头疼了好几天,特地记录一下。RecyclerView为了性能考虑复用无可厚非,所以打算并且抽时间深度研究一下RecyclerView的复用机制。

你可能感兴趣的:(Android)