Android 自定义 BaseAdapter

我们在 Android 自定义 Adapter 中自定义了一个 YetAdapter 的适配器,用了好几次,都感觉不错,但那是数据量比较少的情况下,如果数据量一多,就特别卡顿,有时候会导致卡死,是什么原因造成的呢?

是因为 getView() 方法,界面上有多少列就会调用多少次 getView() ,每次都是新 inflate 一个 View,都要进行这个 XML 的解析,这样会 很浪费资源

所以我们要对 YetAdapter 进行优化,有两个目标

  1. 复用 convertView
  2. ViewHolder 重用组件,不用每次都 `findViewById()

复用 ConvertView

因为界面上有多少个 Item,就要调用 getView() 多少次

我们先来看看之前的方法是什么样的?

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

    convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item,parent,false);

    ImageView img_icon = (ImageView) convertView.findViewById(R.id.icon);
    TextView txt_aName = (TextView) convertView.findViewById(R.id.name);
    TextView txt_aDesc = (TextView) convertView.findViewById(R.id.desc);

    img_icon.setBackgroundResource(mData.get(position).getaIcon());
    txt_aName.setText(mData.get(position).getaName());
    txt_aDesc.setText(mData.get(position).getaDesc());

    return convertView;
}

从代码里可以看出,inflate()每次都要加载一次 xml

其实这个 convertView 是系统提供给我们的可供服用的 View ,既然可复用,那么只要做一下判断就好

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

    if(convertView == null){

        convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item,parent,false);
    }

    ImageView img_icon = (ImageView) convertView.findViewById(R.id.icon);
    TextView txt_aName = (TextView) convertView.findViewById(R.id.name);
    TextView txt_aDesc = (TextView) convertView.findViewById(R.id.desc);

    img_icon.setBackgroundResource(mData.get(position).getaIcon());
    txt_aName.setText(mData.get(position).getaName());
    txt_aDesc.setText(mData.get(position).getaDesc());

    return convertView;
}

ViewHolder 重用组件

上面的优化只做到了 XML 文件只加载一次,但 convertView.findViewById 还是调用了多次

其实我们的 ListView 中的每一项都是一模一样的布局,能否只调用一次就好?

答案是肯定的,但需要自己定义一个 ViewHolder 类来对这一部分进行性能优化

ViewHolder 其实就是一个静态类

static class ViewHolder{
    ImageView img_icon;
    TextView txt_aName;
    TextView txt_aSpeak;
}

然后修改 getView()

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

    ViewHolder holder = null;

    if(convertView == null){

        convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item,parent,false);

        holder = new ViewHolder();

        ImageView img_icon = (ImageView) convertView.findViewById(R.id.icon);
        TextView txt_aName = (TextView) convertView.findViewById(R.id.name);
        TextView txt_aDesc = (TextView) convertView.findViewById(R.id.desc);

        convertView.setTag(holder);   //将Holder存储到convertView中
    }else{
        holder = (ViewHolder) convertView.getTag();
    }

    img_icon.setBackgroundResource(mData.get(position).getaIcon());
    txt_aName.setText(mData.get(position).getaName());
    txt_aDesc.setText(mData.get(position).getaDesc());

    return convertView;
}

好了,完成后我们的 YetAdapter 就是这样了

package cn.twle.android.yetadapter;

import android.content.Context;
import android.widget.BaseAdapter;

import android.widget.TextView;
import android.widget.ImageView;

import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;

import java.util.LinkedList;

public class YetAdapter extends BaseAdapter {

    private LinkedList<YetLanguage> mData;
    private Context mContext;

    public YetAdapter(LinkedList<YetLanguage> mData, Context mContext) {

        this.mData = mData;
        this.mContext = mContext;
    }

    @Override
    public int getCount() {
        return mData.size();
    }

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

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

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

        ViewHolder holder = null;

        if(convertView == null){

            convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item,parent,false);

            holder = new ViewHolder();

            holder.img_icon = (ImageView) convertView.findViewById(R.id.icon);
            holder.txt_aName = (TextView) convertView.findViewById(R.id.name);
            holder.txt_aDesc = (TextView) convertView.findViewById(R.id.desc);

            convertView.setTag(holder);   //将Holder存储到convertView中
        }else{
            holder = (ViewHolder) convertView.getTag();
        }

        holder.img_icon.setBackgroundResource(mData.get(position).getaIcon());
        holder.txt_aName.setText(mData.get(position).getaName());
        holder.txt_aDesc.setText(mData.get(position).getaDesc());

        return convertView;
    }


    static class ViewHolder{
        ImageView img_icon;
        TextView txt_aName;
        TextView txt_aDesc;
    }
}

Android ListView 列表视图 最后一个范例中的 YetAdapter 替换一下,发现正常运行

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.