ListView,GridView,RecyclerView滑动错位的终极解决办法

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u012237192/article/details/72917905

直接讲重点!

假如你的item布局里面包含但不限于这些东西:textView,ImageView,CheckBox,Button...




你一定遇到过滑动列表时item里面的控件错位,该出现的地方不出现,不该出现的地方反而蹦出来的情况。


我也在网上看过很多解决办法,很多说给什么控件设置一个tag呀之类的,看着我都觉得麻烦,其实解决滑动错位并不需要设置什么tag,就一个if-else就能解决。


下面正片!

问题的所在就是你的adapter里面,这里我们直接看一个最简单ListView 的Adapter,其他的GridView,RecyclerView原理也是一模一样,就不多赘述。


直接看adapter里面的getView方法:


@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.item_layout, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.title = (TextView) convertView.findViewById(R.id.title);
            viewHolder.image = (ImageView) convertView.findViewById(R.id.image);
            viewHolder.check = (CheckBox) convertView.findViewById(R.id.check);
            viewHolder.button = (Button) convertView.findViewById(R.id.button);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        ListViewBean listViewBean = mList.get(position);
        viewHolder.title.setText(listViewBean.getTitle());
        //绑定数据

        //重点!!!

        //滑动导致item里面的控件错位

        //第一种情况
        // 数据绑定之后滑动错位
        //很多情况我们会写如下代码
        //根据image的路径是否为空来给ImageView赋值
        //你可能认为逻辑没错,如果iamgePath有路径那么才给图片赋值
        //但是运行之后,全TM乱了
        if (!"".equals(listViewBean.getImagePath())) {
            viewHolder.image.setImageURI(Uri.parse(listViewBean.getImagePath()));
        }

        //解决方案:只需要再加上一个else就够了
        //为什么加上一个else就不会错位了?
        //我也懒得给你们讲缓存什么的(我也不会讲)
        //通俗易懂的来说:
        // 当进入listViewBean.getImagePath()有路径的时候,
        // 程序进了if里面,里面明确规定了我要把路径赋值给imageView,程序就照着我规定的做
        // 但是,如果listViewBean.getImagePath()是空的时候,程序不会进入if,
        // 不仅没进if,而且你也没在任何地方给他规定路径是空的时候他应该做什么
        // 那他就只能胡乱给你填数据咯
        if (!"".equals(listViewBean.getImagePath())) {
            viewHolder.image.setImageURI(Uri.parse(listViewBean.getImagePath()));
        } else {
            //所以当路径为空时,也必须规定该控件应该怎么做
            viewHolder.image.setImageResource(R.mipmap.ic_launcher);
        }

        // 第二种情况:
        //设置某一控件显示或者隐藏

        //下面的代码,我定义了一个boolean类型的属性,用来判断我的checkBox是否显示
        //单当你运行之后就会发现,checkBox错位了
        if (listViewBean.isDisPlayCheck()) {
            viewHolder.check.setVisibility(View.VISIBLE);
        }

        //解决方案:同样也只需要加上一个else
        //代码修改如下,button也同样
        if (listViewBean.isDisPlayCheck()) {
            viewHolder.check.setVisibility(View.VISIBLE);
        } else {
            viewHolder.check.setVisibility(View.GONE);
        }
        if (listViewBean.isDisPlayButton()) {
            viewHolder.button.setVisibility(View.VISIBLE);
        } else {
            viewHolder.button.setVisibility(View.GONE);
        }
        return convertView;
    }


总结:只要是在ViewHolder里面声明了的控件,要么不赋值,要么在所有分支都赋值,有if,就一定要有else,要让控件无论进入哪一个分支都明白自己应该做什么事

展开阅读全文

没有更多推荐了,返回首页