打造萬能適配器 (80行-25行代碼)極限優化

極限.jpg

android中像是ListView和girdview 這種組件在項目中使用頻率很是高, adapter 也是每次必寫的玩意 合理的封裝 優化 可使得咱們的寫更少的代碼 作更多的事情.android

如下文章闡述瞭如何從80行代碼 優化到 25行ide

ViewHolder 優化

傳統的ViewHolder 通常都在自定義的adapter去編寫,而且每個adapter都會對應一個自定義的內部類viewholder.優化

MyAdapter 中 viewHolder 部分代碼:this

private class ViewHolder{

        TextView  userName;
        TextView  userAge;
        TextView  userAddress;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;
        if(convertView == null){
            convertView = mInflater.inflate(this.layout,parent,false);
            holder = new ViewHolder();

            holder.userName = (TextView) convertView.findViewById(R.id.user_name);
            holder.userAge = (TextView) convertView.findViewById(R.id.user_age);
            holder.userAddress = (TextView) convertView.findViewById(R.id.user_address);

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

        return convertView;
    }

優化方案 : 將各零散 viewHolder 抽象成一個通用類 適配全部自定義的adapter 而且viewHolder的相關業務 從adapter中 放到 通用viewHolder中.spa

抽象以後 使用通用viewHolder 1行代碼code

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
       ViewHolder viewHolder = ViewHolder.get(context, convertView, parent, position, layout);
       return viewHolder.getConvertView();
    }

得到控件咱們就能夠用通用類中封裝好的方法getView(int id)對象

TextView textView = viewHolder.getView(R.id.user_name);

如下 ViewHolder 公共類 :繼承

/**
 * 抽象公共的viewholder
 * Created by sherlock on 15/12/17.
 */
public class ViewHolder {

    private SparseArray<View> mViews;
    private int mPosition;
    private View mConvertView;

    public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {
        this.mPosition = position;
        this.mViews = new SparseArray<>();
        this.mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false);

        mConvertView.setTag(this);
    }

    /**
     * 獲取viewholder
     * @param context
     * @param converView
     * @param parent
     * @param position
     * @param layoutId
     * @return
     */
    public static ViewHolder get(Context context, View converView, ViewGroup parent, int position, int layoutId) {
        if (converView == null) {
            return new ViewHolder(context, parent, layoutId, position);
        } else {
            ViewHolder holder = (ViewHolder) converView.getTag();
            //viewholderr會被複用 及時更新下position
            holder.mPosition = position;
            return holder;
        }
    }



    /**
     * 取得viewholder存儲的的控件
     * @param viewId
     * @param <T>
     * @return
     */
    public <T extends View> T getView(int viewId) {
        View view = mViews.get(viewId);
        if(view == null){
            view = mConvertView.findViewById(viewId);
            mViews.put(viewId,view);
        }

        return (T) view;
    }


    public View getConvertView() {
        return mConvertView;
    }

}

Adapter優化

咱們創建一個CommonAdapter 繼承自BaseAdapterrem

public abstract class CommonAdapter<T> extends BaseAdapter {

  protected LayoutInflater mInflater;
  protected int layout;
  protected Context context;
  protected List<T> dataList;

  public CommonAdapter(Context context, int layout, List<T> dataList) {
      this.context = context;
      this.layout = layout;
      this.dataList = dataList;
      this.mInflater.from(context);
  }

  @Override
  public int getCount() {
      return dataList.size();
  }

  @Override
  public T getItem(int position) {
      return dataList.get(position);
  }

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

  @Override
  public abstract  View  getView(int position, View convertView, ViewGroup parent);


}

使用commonAdapter,代碼是否是精簡不少 咱們還能夠繼續優化:get

public class MyAdapter extends CommonAdapter<User> {

    public MyAdapter(Context context, int layout,List<User> dataList) {
        super(context,layout,dataList);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = ViewHolder.get(context, convertView, parent, position, layout);
        //使用
        TextView textView = viewHolder.getView(R.id.user_name);
        return viewHolder.getConvertView();
    }

}

我能夠作到讓使用者更加專一他們的業務, 能夠將
ViewHolder viewHolder = ViewHolder.get(context, convertView, parent, position, layout);
return viewHolder.getConvertView();
兩部分代碼 繼續封裝 複用

在CommonAdapter中加入 一個抽象方法
public abstract void convert(ViewHolder holder,T t);
在commonAdapter中實現getView

@Override
    public View  getView(int position, View convertView, ViewGroup parent){
        ViewHolder viewHolder = ViewHolder.get(context, convertView, parent, position, layout);
        convert(viewHolder,getItem(position));
        return viewHolder.getConvertView();
    }

咱們的MyAdapter來實現convert 這個部分就是暴露給 使用者的部分 在這裏能夠拿到一個holde如和 對應業務bean的倆個對象 讓你專一填業務

超級清爽

public class MyAdapter extends CommonAdapter<User> {

    public MyAdapter(Context context, int layout,List<User> dataList) {
        super(context,layout,dataList);
    }

    @Override
    public void convert(ViewHolder holder, User user) {
        //使用
        TextView textView = holder.getView(R.id.user_name);
        textView.setText(user.getUserName());
    }
}

極限優化 1行代碼

咱們能夠經過鏈式調用來實現這個效果,咱們在ViewHolder中 寫2個輔助方法

public ViewHolder setText(int viewId,String text){
        TextView textView = getView(viewId);
        textView.setText(text);
        return this;
    }
    
   public ViewHolder setImageResource(int viewId,int resId){
        ImageView imageView = getView(viewId);
        imageView.setImageResource(resId);
        return this;
    }

能夠根據你的控件狀況 來封裝不一樣的方法.

使用起來很easy了 呵呵 真的一行足矣

public class MyAdapter extends CommonAdapter<User> {

    public MyAdapter(Context context, int layout, List<User> dataList) {
        super(context, layout, dataList);
    }

    @Override
    public void convert(ViewHolder holder, User user) {
        holder  .setText(R.id.user_name, user.getUserName())
                .setText(R.id.user_age, user.getUserAge())
                .setText(R.id.user_address, user.getUserAddress());

    }

}

文章同步發佈在 http://www.jianshu.com/p/1d80...

相關文章
相關標籤/搜索