一般不优化的adapter通常继承自BaseAdapter会出现一下几个问题:
- getCount(), getItem(), getItemId()代码都要去重写,一个adapter还行,如果adapter越来越多的话,每个adapter都这么写就超级恶心了。
- 就是getview里面if else 对convertview的判断的代码也是每个adapter都要去写,超级恶心。
- 然后就是如果优化adapter的findviewByid的加载,肯定要使用viewholder,那么每个adapter里面都写viewholder,恶心。
那么如何解决这问题呢:
- 首先就是getcount,getitem(),getitemId的代码最好在父类去实现,子类继承,就能让子类继承这些方法,而不用去多余写这些代码,实现代码重用。
- 考虑业务需求,如果有下拉刷新,上拉加载更多的操作,肯定有刷新adapter中list数据,也坑定有加载更多的方法,写到每个adapter里面既不美观,代码里面总是要带个notifydatesetchange的代码,恶心,因此这些操作可以封装到父类中去,比如如下的updateListview,addBottom操作。
- 对getview里面对viewholder以及频繁的findviewByd进行简化操作,封装到如下的viewholder类里面去,其中getViewHolder()方法简化了每个adapter的判断convertview是否为null以及settag的操作,getView()简化findviewByid的操作。
1 public abstract class EasyAdapter<T> extends BaseAdapter { 2 private LayoutInflater inflater; 3 private int layoutId; 4 private List<T> mlist = new ArrayList<T>(); 5 6 public EasyAdapter(Context context, int layoutId, List<T> list) { 7 super(); 8 this.inflater = LayoutInflater.from(context); 9 this.layoutId = layoutId; 10 this.mlist = list; 11 } 12 13 /** 14 * 往顶部添加数据 15 * 16 * @param list 17 */ 18 public void add2Head(List<T> list) { 19 mlist.addAll(0, list); 20 notifyDataSetChanged(); 21 } 22 23 public void clearAll() { 24 mlist.clear(); 25 notifyDataSetChanged(); 26 } 27 28 public List<T> getAllList() { 29 return mlist; 30 } 31 32 /** 33 * 往底部添加数据 34 * 35 * @param list 36 */ 37 public void add2Bottom(List<T> list) { 38 mlist.addAll(list); 39 notifyDataSetChanged(); 40 } 41 42 public void add2Bottom(T t) { 43 mlist.add(t); 44 notifyDataSetChanged(); 45 } 46 47 /** 48 * @Title: updateListView 49 * @Description: TODO(更新BaseAdapter中的数据) 50 * @param @param list 设定文件 51 * @return void 返回类型 52 * @throws 53 */ 54 public void updateListView(List<T> list) { 55 mlist = list; 56 notifyDataSetChanged(); 57 } 58 59 @Override 60 public int getCount() { 61 return mlist.size(); 62 } 63 64 @Override 65 public T getItem(int position) { 66 return mlist.get(position); 67 } 68 69 @Override 70 public long getItemId(int position) { 71 72 return position; 73 } 74 75 /** 76 * 实际显示View的方法,使用抽象方法强制调用者覆写! 77 */ 78 @Override 79 public View getView(int position, View convertView, ViewGroup parent) { 80 81 ViewHolder viewHolder = ViewHolder.getViewHolder(parent, convertView, 82 inflater, layoutId); 83 convert(viewHolder, mlist.get(position)); 84 return viewHolder.getConvertView(); 85 86 } 87 88 public abstract void convert(ViewHolder viewHolder, T t); 89 90 }
ViewHolder 的封装:
1 public class ViewHolder { 2 private SparseArray<View> views; 3 private View convertView; 4 5 public ViewHolder(ViewGroup parent,LayoutInflater inflater,int layoutId) { 6 this.views = new SparseArray<View>(); 7 this.convertView = inflater.inflate(layoutId,parent,false); 8 this.convertView.setTag(this); 9 } 10 11 /** 12 * 得到viewHolder 13 * @param parent 14 * @param convertView 15 * @param inflater 16 * @param layoutId 17 * @return 18 */ 19 public static ViewHolder getViewHolder(ViewGroup parent,View convertView,LayoutInflater inflater,int layoutId){ 20 if (convertView==null){ 21 return new ViewHolder(parent,inflater,layoutId); 22 } 23 return (ViewHolder) convertView.getTag(); 24 } 25 26 /** 27 * 得到convertView 28 * @return 29 */ 30 public View getConvertView() { 31 return convertView; 32 } 33 34 /** 35 * 根据Id得到view 36 * @param viewId 37 * @param <T> 38 * @return 39 */ 40 public <T extends View>T getView(int viewId){ 41 View view = views.get(viewId); 42 if (view==null){ 43 view = convertView.findViewById(viewId); 44 views.put(viewId,view); 45 } 46 return (T) view; 47 } 48 49 /** 50 * 根据id得到TextView 51 * @return 52 */ 53 public TextView getTextView(int viewId){ 54 return getView(viewId); 55 } 56 /** 57 * 根据id得到ImageView 58 * @return 59 */ 60 public ImageView getImageView(int viewId){ 61 return getView(viewId); 62 } 63 /** 64 * 根据id得到Button 65 * @return 66 */ 67 public Button getButton(int viewId){ 68 return getView(viewId); 69 } 70 /** 71 * 根据id得到RadioButton 72 * @return 73 */ 74 public RadioButton getRadioButton(int viewId){ 75 return getView(viewId); 76 } 77 /** 78 * 根据id得到CheckBox 79 * @return 80 */ 81 public CheckBox getCheckBox(int viewId){ 82 return getView(viewId); 83 } 84 /** 85 * 根据id得到ImageButton 86 * @return 87 */ 88 public ImageButton getImageButton(int viewId){ 89 return getView(viewId); 90 } 91 /** 92 * 根据id得到ImageButton 93 * @return 94 */ 95 public EditText getEditText(int viewId){ 96 return getView(viewId); 97 } 98 99 /** 100 * 根据id得到RelativeLayout 101 * @return 102 */ 103 public RelativeLayout getRelativeLayout(int viewId){ 104 return getView(viewId); 105 } 106 }
下面是在项目中的使用,可见效果是如此的简洁和高效:
-
1 public class MainAdapter extends EasyAdapter<MainBean> { 2 3 public MainAdapter(Context context, int layoutId, List<MainBean> list) { 4 super(context, layoutId, list); 5 } 6 7 @Override 8 public void convert(ViewHolder viewHolder, MainBean t) { 9 ImageView imageView = viewHolder.getImageView(R.id.imageview); 10 TextView textView = viewHolder.getTextView(R.id.textView); 11 ImageLoader.getInstance().displayImage(t.getImageUrl(), imageView); 12 textView.setText(t.getContent()); 13 } 14 }