Android listview item 错位

347 查看

listvie 上下滑动前

listview 上下滑动后

这周开发时又遇到过这种情况,其实当时已经解决了,但没有做笔记有给忘了,折腾了好一会而才想起怎么处理,虽然简单但还是写篇博文记一下,但也因为网络上的博文有的写的太。。。虽然他解决了也写了博文让后人参考,但能不能把意思,思路给讲清楚啊,蛋疼。。。
好了,废话不多说:
出现这种 adapter 的 item 错位的原因是 我们往往是为了 listview 的性能 将 item 进行复用 , 将 adapter 的

 @Override
 public View getView(int position, View convertView, ViewGroup parent)

中的 convertView 做个判断,如果已经存在就不再进行实例化了,虽然性能得到了很大提升,但也就出现了上面提到的那问题,item 出现错位。

既然知道了原因,那除了就简单了,有的建议 那不将 convertView 复用不久完了,但性能也大大下降,也是不可取得。所以可以对item 的 view做个 判断再显示即可,具体看下代码:


/** ListAdapter
 * @ClassName: ListAdapter
 * @Description: TODO
 * @author zts
 * @date 2016-4-9  16:26
 */
public class ListAdapter extends  BaseListAdapter<String> {

    private List<String> strFlag = new ArrayList<String>();

    public ListAdapter(Context context, List<String> list) {
        super(context, list);
    }
    @Override
    public View bindView(final int position, View convertView, ViewGroup parent) {
      
        String item = list.get(position);
       
        if(convertView == null){
            convertView = mInflater.inflate(R.layout.list_item,null);
        }
        final TextView textView = ViewHolder.get(convertView,R.id.text_View);
        final ImageView selectImg = ViewHolder.get(convertView,R.id.select_img);
        
        textView.setText(item);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            if (strFlag.contains(position + "")) {
                    strFlag.remove(position + "");
                    selectImg.setVisibility(View.GONE);

                } else {
                    strFlag.add(position + "");
                    selectImg.setVisibility(View.VISIBLE);
                }
            }
        });

        if (strFlag.contains(position+"")) {
            selectImg.setVisibility(View.VISIBLE);
        } else {
            selectImg.setVisibility(View.GONE);
        }
        return convertView;
    }
}

上面的 bindView 其实是被 getView 做个 ViewHolder 封装而已,一样的,接下来简单分析下代码:
一般我们在 adapter的 item 处理 view 的点击事件是这样的:

       textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(selectImg.getVisibility() == View.VISIBLE){
                    selectImg.setVisibility(View.GONE);
                }else{
                    selectImg.setVisibility(View.VISIBLE);
                }
        });

这样做肯定是会出现 item 的 view显示错位的问题的,因为 selectImg 的 VISIBLE 或 GONE 只在 setOnClickListener 发生,而当你 对 listview 上下滑动的时候 根本就不会出发 对于 position 的 setOnClickListener 方法,而又 convertView 是复用的,那当然就显示的乱七八糟了。
所以我在代码的 setOnClickListener 和 bindView 方法里面加了标识:

private List<String> strFlag = new ArrayList<String>();
strFlag.contains(position + "")

注意是 setOnClickListener 和 bindView ,setOnClickListener 是点击事件判断标识,bindView 是为了listview 上下滑动 刷新 item 也要做标识,这步也是解决 item 错位的关键啦,这篇文章重点就是这里咯。

好了问题解决了,如果对 BaseListAdapter 重构好的代码 bindView 感兴趣的话可以去我的
github 查看,我已经把完整代码 git 上去咯 ,我觉得 重构后的 BaseAdapter 更简单好用哦。

github:https://github.com/ZengTianShengZ/listvi...