Adapter优化(一)convertView和ViewHolder机制

来源:互联网 发布:太平洋炒股软件下载 编辑:程序博客网 时间:2024/05/16 14:21

一、初步
像ListView、GridView这些组件通常需要使用setAdapter方法传入一个适配器,这个Adapter的作用,初步理解就是把一个xml形式的item返回成View给组件吧(理论知识先挖坑)

二、从BaseAdapter说起
我们自定义一个MyAdapter通常是继承BaseAdapter
然后复写其中的四个抽象方法

getCount();getItemId();getItem();getView();

前三个方法今天不说,只给个代码
我要显示的item是一组网络图片,图片的uriString[] imgUrls

        @Override        public int getCount() {            return imgUrls.length;        }        @Override        public long getItemId(int position) {            return position;        }        @Override        public Object getItem(int position) {            return imgUrls[position];        }

重点说的是第四个方法getView()
先要知道getView() 是要返回一个item的View对象
(1)、简单但效率低的方法

    @Override    public View getView(int position, View convertView, ViewGroup parent) {        //新生成一个View item        View item = getLayoutInflater().inflate(R.layout.item_list,null);        //新建一个ImageView  TextView        ImageView image = (ImageView)item.findViewById(R.id.iv_list);        TextView text = (TextView)item.findViewById(R.id.tv_list);        //修改img text        image.setImageResource(R.drawable.pic);        text.setText("ITEM"+(position+1));        return item;    }

这个方法需要生成大量的View。Android有个回收器Recycler机制,比如一个页面能够容下7个item,那么当你看到第1-7个item的时候,回收器是空的,但是当你下滑,到第8个item时,(第1个被完全滑出屏幕),这个item1就会进入回收器。
getView()方法的参数convertView就是存储这个回收器中的View,我们利用这个参数进行优化。

(2)、利用convertView进行优化

    @Override        public View getView(int position, View convertView, ViewGroup parent) {            //加了这个判断后,新建View只会执行一次            if(convertView ==  null) {                convertView = getLayoutInflater().inflate(R.layout.item_list,null);              }            ImageView image = (ImageView)convertView.findViewById(R.id.iv_list);            TextView text = (TextView)convertView.findViewById(R.id.tv_list);                convertView.setTag(viewHolder);            image.setImageResource(R.drawable.pic);            text.setText("ITEM"+(position+1));            return convertView;        }

以上方法避免了多次生成View而是利用convertView来返回View,但是findViewById()还是执行很多次。
于是我们新定义一个类ViewHolder来封装每一个item里面的子组件(大概是这个意思吧,就是每一个item里面也许又有图片文字那些),用convertViewsetTag()方法把ViewHolder(也就是打包的子组件)和convertView联系在一起。
下次要用convertView的时候,用getTag()方法就可以得到ViewHolder了,也就不用findViewById()再获取了。
(3)、利用ViewHolder再进行优化

    //ViewHolder类的定义    public class ViewHolder {           public ImageView image;           public TextView text;       }
@Overridepublic View getView(int position, View convertView, ViewGroup parent) {    ViewHolder viewHolder = null;    if (convertView == null) {        //如果回收器没有View,就生成一个,同时new一个ViewHolder,再初始化里面的组件        convertView = getLayoutInflater().inflate(R.layout.item_list, null);        viewHolder = new ViewHolder();        viewHolder.image = (ImageView) convertView.findViewById(R.id.iv_list);        viewHolder.text = (TextView) convertView.findViewById(R.id.tv_list);        convertView.setTag(viewHolder);    } else {        //直接获取ViewHolder        viewHolder = (ViewHolder) convertView.getTag();    }    viewHolder.image.setImageResource(R.drawable.pic);    viewHolder.text.setText("ITEM" + (position + 1));    return convertView;}
0 0
原创粉丝点击