ListView发生混乱和解决办法

1.发生混乱的原因

ListView发生混乱和解决办法_第1张图片

借用别人的图来解释一下:1.如上图第一屏的7条数据,也就是会产生7条数据和7个新的布局,2.当屏幕滑动第一条数据消失,复用机制就会发生了,先把item1放到recycler中,等待屏幕底部数据出现,3当item8出现时,就会复用item1的布局和数据,。

也可以这样

  public View getView(int position, View convertView, ViewGroup viewGroup) {
            System.out.println("getView" + position + " "+ convertView);
}
可以发现刚创建时前7个item返回的convertment全是null,第8个item出现,conertView就不为空了,这就对应了
if(convertView == null){
//创建布局
}else{
//取tag对应的布局
}
2.由于布局会产生复用,保证了内存的消耗很小,但是也会常常发生混乱的情况

解决办法:a.利用HashMap()

private class ViewHolder{
        private TextView tv_name;
        private TextView tv_age;
        private TextView tv_des;
        private ImageView iv_icon;

        public ViewHolder(View convertView){
           iv_icon = convertView.findViewById(R.id.iv_icon);
           tv_age = convertView.findViewById(R.id.tv_age);
           tv_name = convertView.findViewById(R.id.tv_name);
           tv_des = convertView.findViewById(R.id.tv_des);
        }

    }
//getView()中直接从HashMap去取,HashMap 
 //的对应关系,布局混乱就会避免    private HashMaplamp =new HashMap<>();
 @Override
        public View getView(int position, View convertView, ViewGroup viewGroup) {
            System.out.println("getView" + position + " "+ convertView);
            ViewHolder holder ;
            if (lamp.get(position)== null){
                convertView = getLayoutInflater().inflate(R.layout.item_first_fragment,null);
                holder = new ViewHolder(convertView);
                convertView.setTag(holder);
                lamp.put(position , convertView);
            }else {
                convertView = lamp.get(position);
                holder = (ViewHolder) convertView.getTag();
            }
                holder.tv_des.setText(mData.get(position).getDes());
                holder.tv_name.setText(mData.get(position).getName());
                holder.tv_age.setText(String.valueOf(mData.get(position).getAge()));
                if (position == 1 || position == 3){
                    holder.iv_icon.setImageResource(R.drawable.play);
                }else {
                    holder.iv_icon.setVisibility(View.GONE);
                }
            return convertView;
        }

b,判断语句一定一定一定(三遍)要有if对应的else

    例如

if (position == 1 || position == 3){
     holder.iv_icon.setImageResource(R.drawable.play);
}else {
     holder.iv_icon.setVisibility(View.GONE);
}
c.大牛封装的CommonAdapter,亲测可用,还不用写ViewHolder了,方便
public  abstract class CommonAdapter extends BaseAdapter {
    @Override
    public int getCount() {
        return getDataCount();
    }



    @Override
    public Object getItem(int i) {
        return i;
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        if (null==view){
            view  = getContentView(position,view,parent);//view为空就去创建view
            HashMapviews = new HashMap<>();//用hashMap存储view,这样就有了对应关系,每个position对应一个view
            view.setTag(views);

        }
        bindData(position , view);
        return view;
    }
    public T getViewById(Class c , View convertView , int resId){
        HashMap views = (HashMap) convertView.getTag();
        if (null == views){
            views = new HashMap<>();
        }
        View view = views.get(resId);
        if (null == view){
            view = convertView.findViewById(resId);
            views.put(resId,view);
        }
        convertView.setTag(views);
        return c.cast(view);
    }
    public  T getViewById(View convertView , int resId){
        return (T)getViewById(View.class , convertView , resId);
    }
    public abstract View getContentView(int position , View convertView , ViewGroup parent);

    public abstract int getDataCount();
    public abstract void bindData(int position , View convertView);
}

d.解决图片混乱的问题

原因:如果网络加载图片,本身item的图片还未来的及加载,就直接复用了其他item的图片了

// 给 ImageView 设置一个 tag
holder.img.setTag(imgUrl);
// 预设一个图片
holder.img.setImageResource(R.drawable.ic_launcher);

// 通过 tag 来防止图片错位
if (imageView.getTag() != null && imageView.getTag().equals(imageUrl)) {
    imageView.setImageBitmap(result);
}


你可能感兴趣的:(Android)