// 很多人在使用自定义适配器的时候存在执行效率低,内存消耗大,代码
// 不够优化的问题,下面列出Android 几种自定义适配器的写法
第一种方式没有实现布局对象的复用,使用自定义适配器中上下文与资源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;
}
}
}