Adapter优化(一)convertView和ViewHolder机制

一、初步
像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;
       }
@Override
public 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 开发 ListView 或 RecyclerView 时,为了提高列表的滑动流畅度和性能表现,通常会采用 ViewHolder 模式。ViewHolder 是一个用于保存 convertView View 的对象,可以通过 view.setTag() 方法将其与 convertView 绑定起来。在 getView() 或 onCreateViewHolder() 方法,如果 convertView 不为 null,则可以直接使用 convertView,并调用 getTag() 方法获取 ViewHolder 对象,避免频繁地调用 findViewById() 方法。这样可以大大减少 UI 线程的工作量,提高应用的性能表现。 具体实现步骤如下: 1. 在 Adapter 定义 ViewHolder 类,用于保存 convertView View 的对象。 ```java class ViewHolder { TextView title; ImageView icon; } ``` 2. 在 getView() 或 onCreateViewHolder() 方法,通过 convertViewViewHolder 实现优化。 ```java @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false); viewHolder = new ViewHolder(); viewHolder.title = convertView.findViewById(R.id.title); viewHolder.icon = convertView.findViewById(R.id.icon); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } // 设置子 View 的数据 viewHolder.title.setText(getItem(position).getTitle()); viewHolder.icon.setImageResource(getItem(position).getIconResId()); return convertView; } ``` 在上述代码,如果 convertView 不为 null,则通过 convertView.getTag() 方法获取 ViewHolder 对象,否则创建新的 convertViewViewHolder 对象,并将其绑定起来,最后设置子 View 的数据并返回 convertView。 这样,就可以通过 ViewHolder 模式优化列表的性能表现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值