listView的优化方式
重用convertView |
viewHolder |
static class viewHolder |
在列表里面有图片的情况下,监听滑动不加载图片 |
多个不同布局,可以创建不同的viewHolder和convertView进行重用 |
ViewHolder不是Android的开发API,而是一种设计方法,就是设计个静态类,缓存一下,省得Listview更新的时候,还要重新操作。
1、正常ViewHolder写法
public class MyAdapter extends BaseAdapter {
private ArrayList<FileInfo > listFileInfo;
private Context context;
public MyAdapter(ArrayList<FileInfo> listFileInfo, Context context) {
this.listFileInfo = listFileInfo;
this.context = context;
}
@Override
public int getCount() {
return listFileInfo.size();
}
@Override
public Object getItem(int position) {
return listFileInfo.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder=null;
if (convertView==null){
convertView= LayoutInflater.from(context).inflate(R.layout.list_item,null);
viewHolder=new ViewHolder();
viewHolder.btnStart=convertView.findViewById(R.id.btnStart);
viewHolder.btnStop=convertView.findViewById(R.id.btnStop);
viewHolder.tvFileName=convertView.findViewById(R.id.tvFileName);
viewHolder.progressBar=convertView.findViewById(R.id.progressBar);
convertView.setTag(viewHolder);
}else{
viewHolder= (ViewHolder) convertView.getTag();
}
FileInfo fileInfo=listFileInfo.get(position);
viewHolder.tvFileName.setText(fileInfo.getFileName());
viewHolder.btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
viewHolder.btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
return convertView;
}
static class ViewHolder{
private TextView tvFileName;
private Button btnStart, btnStop;
private ProgressBar progressBar;
}
2、使用万能ViewHolder
**
* 万能ViewHolder
*/
public class CommonViewHolder {
/**
* @param view 所有缓存View的根View
* @param id 缓存View的唯一标识
* @return
*/
public static <T extends View> T get(View view, int id) {
//SparseArray(稀疏数组).他是Android内部特有的api,标准的jdk是没有这个
// 类的.在Android内部用来替代HashMap<Integer,E>这种形式,使用SparseArray
// 更加节省内存空间的使用,SparseArray也是以key和value对数据进行保存的.
// 使用的时候只需要指定value的类型即可.并且key不需要封装成对象类型.
SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
//如果根view没有用来缓存View的集合
if (viewHolder == null) {
viewHolder = new SparseArray<View>();
view.setTag(viewHolder);//创建集合和根View关联
}
View chidlView = viewHolder.get(id);//获取根View储存在集合中的孩纸
if (chidlView == null) {//如果没有改孩纸
//找到该孩纸
chidlView = view.findViewById(id);
viewHolder.put(id, chidlView);//保存到集合
}
return (T) chidlView;
}
}
public class MyAdapter extends BaseAdapter {
private ArrayList<FileInfo > listFileInfo;
private Context context;
public MyAdapter(ArrayList<FileInfo> listFileInfo, Context context) {
this.listFileInfo = listFileInfo;
this.context = context;
}
@Override
public int getCount() {
return listFileInfo.size();
}
@Override
public Object getItem(int position) {
return listFileInfo.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView==null) {
convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
}
Button btnStart= CommonViewHolder.get(convertView,R.id.btnStart);
Button btnStop= CommonViewHolder.get(convertView,R.id.btnStop);
TextView tvFileName= CommonViewHolder.get(convertView,R.id.tvFileName);
ProgressBar progressBar= CommonViewHolder.get(convertView,R.id.progressBar);
FileInfo fileInfo=listFileInfo.get(position);
tvFileName.setText(fileInfo.getFileName());
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
return convertView;
}