打造万能适配器 (80行-25行代码)极限优化

打造万能适配器 (80行-25行代码)极限优化_第1张图片

android中像是ListView和girdview 这种组件在项目中使用频率非常高, adapter 也是每次必写的玩意 合理的封装 优化 可以使得我们的写更少的代码 做更多的事情.

以下文章阐述了如何从80行代码 优化到 25行

ViewHolder 优化

传统的ViewHolder 一般都在自定义的adapter去编写,并且每一个adapter都会对应一个自定义的内部类viewholder.

MyAdapter 中 viewHolder 部分代码:

  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中.

抽象之后 使用通用viewHolder 1行代码

  @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 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 
     * @return
     */
    public  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 继承自BaseAdapter

public abstract class CommonAdapter extends BaseAdapter {

  protected LayoutInflater mInflater;
  protected int layout;
  protected Context context;
  protected List dataList;

  public CommonAdapter(Context context, int layout, List 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,代码是不是精简很多 我们还可以继续优化:

  public class MyAdapter extends CommonAdapter {

    public MyAdapter(Context context, int layout,List 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 {

    public MyAdapter(Context context, int layout,List 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 {

    public MyAdapter(Context context, int layout, List 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...

你可能感兴趣的:(adapter,android)