您的位置:首页 > 移动开发 > Android开发

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

2017-06-08 14:53 483 查看
直接讲重点!

假如你的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,要让控件无论进入哪一个分支都明白自己应该做什么事
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐