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

来源:互联网 发布:淘宝双11不发货 编辑:程序博客网 时间:2024/06/05 02:24

直接讲重点!

假如你的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,要让控件无论进入哪一个分支都明白自己应该做什么事

阅读全文
2 0
原创粉丝点击