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; }