美文网首页
打造万能适配器 (80行-25行代码)极限优化

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

作者: sherlock221b | 来源:发表于2015-12-17 11:09 被阅读208次
    极限.jpg

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

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

    ViewHolder 优化

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

    MyAdapter 中 viewHolder 部分代码:
    <pre>
    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;
    }
    

    </pre>

    优化方案 : 将各零散 viewHolder 抽象成一个通用类 适配所有自定义的adapter 并且viewHolder的相关业务 从adapter中 放到 通用viewHolder中.

    抽象之后 使用通用viewHolder <b>1</b>行代码
    <pre>

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

    </pre>

    获得控件我们就可以用通用类中封装好的方法getView(int id)
    <pre>
    TextView textView = viewHolder.getView(R.id.user_name);
    </pre>

    以下 ViewHolder 公共类 :
    <pre>
    /**

    • 抽象公共的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;
    }
    

    }

    </pre>

    Adapter优化

    我们建立一个CommonAdapter 继承自BaseAdapter

    <pre>

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

    }

    </pre>

    使用commonAdapter,代码是不是精简很多 我们还可以继续优化:
    <pre>
    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();
    }
    

    }

    </pre>

    我可以做到让使用者更加专注他们的业务, 可以将
    ViewHolder viewHolder = ViewHolder.get(context, convertView, parent, position, layout);
    return viewHolder.getConvertView();
    两部分代码 继续封装 复用

    在CommonAdapter中加入 一个抽象方法
    public abstract void convert(ViewHolder holder,T t);
    在commonAdapter中实现getView
    <pre>

    @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();
    }
    </pre>

    我们的MyAdapter来实现convert 这个部分就是暴露给 使用者的部分 在这里可以拿到一个holde如和 对应业务bean的俩个对象 让你专注填业务

    超级清爽
    <pre>
    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());
    }
    

    }
    </pre>

    极限优化 1行代码

    我们可以通过链式调用来实现这个效果,我们在ViewHolder中 写2个辅助方法

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

    可以根据你的控件情况 来封装不同的方法.

    使用起来很easy了 呵呵 真的一行足矣
    <pre>

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

    }
    </pre>

    相关文章

      网友评论

          本文标题:打造万能适配器 (80行-25行代码)极限优化

          本文链接:https://www.haomeiwen.com/subject/obhphttx.html