ListView 和RecyclerView的比较

通过比较ListView 和RecyclerView 

现在官方主要推荐RecyclerView,因为其将ViewHolder融入到该组件中,达到重复利用视图,节省内存的目的


首先,分析ListView的实现机制


public class MyAdapter extends BaseAdapter {
    @Override
    public int getCount() {
        return 0;
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return null;
    }
}

新的适配器必须复写以上几个方法,其中,最重要的就是最后一个方法getView();

该方法表示每次创建一个视图就要调用这个方法,那么如果要创建10000个视图呢?当然就要调用一万次,包括你可能要在里面创建的对象,一个对象就创建一万次,所以很伤内存。既然这样那么就用到这个参数convertView。

这个参数表示创建过的回收视图,既然方法给了这个参数,我们就要用起来,优化内存!

所以,在加载视图的时候,首先判断这个回收视图是否为空,如果不为空,则用它,就是这么简单

if (convertView == null) {
                s_holder = new SingleViewHolder();
                convertView = inflater.inflate(R.layout.single_text, parent, false);
                s_holder.singleTextView = (TextView) convertView.findViewById(R.id.my_text_single);
                convertView.setTag(s_holder);
            } else {
                s_holder = (SingleViewHolder) convertView.getTag();
            }
            s_holder.singleTextView.setText("二级部门");
最后返回一个convertView

这里有个holder,代表什么呢?就是你每次创建视图都要findView...这样就创建了对象,而加载很多的时候,就创建很多,但是,其实都是重复的工作,重复的对象,所以,我们创建一个静态类,里面有这几个参数,每次直接赋值给这个类的参数,而不是创建,这样就节省了很多内存。

public static class SingleViewHolder {
        public TextView singleTextView;
    }


以上方法是对于只有一种回收视图的类型,当有两种以上时,就需要用到以下俩个复写方法

@Override
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }

    @Override
    public int getViewTypeCount() {
        return super.getViewTypeCount();
    }


注意,以上的俩个方法默认是只有一种类型的,第一个返回0(type),第二个返回1(count),所以如果你有超过一个以上的自定义,则需要改写

@Override
    public int getItemViewType(int position) {
        if (position % 4 == 0) {
            return TYPE_TITLE;
        } else {
            return TYPE_CONTENT;
        }
    }

    @Override
    public int getViewTypeCount() {
        return TYPE_COUNT;
    }

我这里是这样改写的,TYPE中表示,第一、五、九位置的视图为TYPE TITLE类型,234、567、。。。位置的为TYPE CONTENT类型,所以下面一个方法就表示2种类型,这样你在getView方法中就可以按类型分类来分别获得或者重用对应的视图,比如我是这样写的

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        int viewType = getItemViewType(position);

        if (viewType == TYPE_TITLE) {
            SingleViewHolder s_holder;

            if (convertView == null) {
                s_holder = new SingleViewHolder();
                convertView = inflater.inflate(R.layout.single_text, parent, false);
                s_holder.singleTextView = (TextView) convertView.findViewById(R.id.my_text_single);
                convertView.setTag(s_holder);
            } else {
                s_holder = (SingleViewHolder) convertView.getTag();
            }
            s_holder.singleTextView.setText("二级部门");


        } else if (viewType == TYPE_CONTENT) {
            ViewHolder holder;

            if (convertView == null) {
                holder = new ViewHolder();
                convertView = inflater.inflate(R.layout.text_layout, parent, false);
                holder.textView = (TextView) convertView.findViewById(R.id.my_text);
                holder.circleImage = (CircleImageView) convertView.findViewById(R.id.my_img);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.textView.setText(list.get(position));
            holder.circleImage.setImageResource(images[position % 5]);


        }


        return convertView;
    }

最后出来的效果为


猜你喜欢

转载自blog.csdn.net/shiguiyou/article/details/47304901