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