Android 自定义适配器逐步优化

// 很多人在使用自定义适配器的时候存在执行效率低,内存消耗大,代码
// 不够优化的问题,下面列出Android 几种自定义适配器的写法

  1. 第一种方式没有实现布局对象的复用,使用自定义适配器中上下文与资源id参数获取” 自定义布局对象 ” ,获取到自定义布局对象之后,便可以根据,控件Id找到各个控件,返回值为你自定义对象的一个界面,容器中需要多项,自定义布局的界面来填充

    /*
    //第一种方式:没有实现布局对象的复用
    // TODO 生成显示数据项的布局对象
    //根据布局的xml文件生成布局对象
    //得到LayoutInflater对象
    LayoutInflater inflater = ((Activity)context).getLayoutInflater();
    //LayoutInflater对象可以根据布局的xml文件生成布局对象
    //第二个参数必须是null,因为如果不是null,会去调用ListView的addView()方法,而ListView没有这个方法
    View view = inflater.inflate(resourceId, null);
    //System.out.println(“=====”+view);
    //convertView接收的是可复用的布局对象,当没有可复用的布局对象时,接收的是null
    //System.out.println(“=====”+convertView);
    //把要显示的数据放到布局对象中的TextView上,得到TextView对象
    //从整体的布局对象中获取TextView对象
    TextView textView = (TextView) view.findViewById(R.id.textView);
    //给textView的text属性设置为当前显示的数据项
    textView.setText(datas.get(position).toString());
    return view;

/方式二:利用convertView 实现了 布局对象的复用,一个布局对象,就是容器中显示的一个条目,由于手机屏幕大小优先,当之前的布局项滑出屏幕时,
之后的,条目复用之前滑出屏幕的条目

    //convertView接收的是可复用的布局对象,当没有可复用的布局对象时,接收的是null
    //先判断是否有可复用的
    /*if(convertView==null){   // 一条一条  从convertView 中去拿
        //convertView = LayoutInflater.from(context).inflate(resourceId, null);
        convertView = LayoutInflater.from(context).inflate(resourceId, parent, false);
    }
    //得到布局对象中的TextView对象
    //每次都要findViewById,影响程序性能
    TextView tv = (TextView) convertView.findViewById(R.id.textView);
    tv.setText(datas.get(position).toString());
    return convertView;*/







    //第三种方式:减少findViewById执行的次数

在执行过一次findViewById 之后,自定义布局内,控件的id值存入
ViewHolder的全局变量中,下次赋值的时候 ,直接从类中出即可

    ViewHolder holder = null;
    if(convertView ==null){
        convertView = LayoutInflater.from(context).inflate(resourceId, parent, false);
        holder = new ViewHolder();
        //让holder中的textView成员指向布局对象中的TextView对象
        holder.textView = (TextView) convertView.findViewById(R.id.textView);
        convertView.setTag(holder);
    }
    else
    {
       holder = (ViewHolder) convertView.getTag();//当可复用时,直接获取holder
    }

    //操作holder中的textView就是操作布局对象中的TextView对象
    holder.textView.setText(datas.get(position).toString());
    return convertView;
}
//通过ViewHolder减少findViewById方法执行的次数
class ViewHolder
{
    TextView textView;
}

// 方式 自定义布局中控件 过多,findViewById 会显得代码不好看
此时我们可以在 ViewHolder中加入一个成员变量,并提供一个getViewById(int ResourceId) 的方法,将convertView的值通过构造方法传入,方法返回控件对象

package com.example.gp11_day10_listview6_cbk1.adapter;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.example.gp11_day10_listview6_cbk1.R;
import com.example.gp11_day10_listview6_cbk1.asynctask.DownTask;
import com.example.gp11_day10_listview6_cbk1.entity.CbkData;

import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public abstract class CbkDataAdapter extends BaseAdapter {

private Context context;
private List<CbkData> datas;

public CbkDataAdapter(Context context, List<CbkData> datas) {
    super();
    this.context = context;
    this.datas = datas;
}

@Override
public int getCount() {
    int count = 0;
    if(datas!=null)
        count = datas.size();
    return count;
}

@Override
public Object getItem(int position) {
    return datas.get(position);
}

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

@Override
public View getView(int position, View convertView, final ViewGroup parent) {
    ViewHolder holder =null;
    if(convertView==null){

        convertView = LayoutInflater.from(context).inflate(R.layout.item_cbk, parent, false);

        holder = new ViewHolder(convertView);

        convertView.setTag(holder);
    }
    else
        holder = (ViewHolder) convertView.getTag();

    //显示数据
    showDatas(holder,datas.get(position));

    return convertView;
}
public abstract void showDatas(ViewHolder holder,CbkData data);

public class ViewHolder
{
    private Map<Integer,View> views;//存放布局对象中的视图对象
    private View itemView;//布局对象

    public ViewHolder(View itemView)
    {
        this.itemView = itemView;
        views = new HashMap<Integer,View>();
    }
    //根据视图的id得到视图对象
    public View getView(int id)
    {
        View view = views.get(id);
        if(view==null)
        {
            view = itemView.findViewById(id);
            views.put(id, view);
        }
        return view;
    }
}

}

你可能感兴趣的:(android,Adapter,自定义适配器)