美文网首页
一步一步手撸Android通用框架 (五)

一步一步手撸Android通用框架 (五)

作者: 844b9a3a3a68 | 来源:发表于2018-03-09 09:59 被阅读48次

目前在越来越多的项目中都会使用到RecyclerView,在这样高频使用的场景,我们应该尝试着进行二次封装,将会减少我们很大的代码量。

演示:

  • new 匿名内部内的方式:
        rl_list.setAdapter(new BaseAdapter<String>(mContext, list, R.layout.item_rl_list) {
            @Override
            public void onBind(ViewHolder holder, int position, String item) {
                holder.view(R.id.iv_img).setBackgroundResource(R.mipmap.ic_launcher).view(R.id.tv_name).setText(item);
            }
        });
  • 对象继承的方式:
TestAdapter testAdapter=new TestAdapter(mContext, list, R.layout.item_rl_list);
rl_list.setAdapter(testAdapter);

public class TestAdapter extends BaseAdapter<String> {

    public TestAdapter(Context context, List<String> mDatas, int layoutId) {
        super(context, mDatas, layoutId);
    }

    @Override
    public void onBind(ViewHolder holder, int position, String item) {
        holder.view(R.id.iv_img).setBackgroundResource(R.mipmap.ic_launcher).setText(R.id.tv_name, item);
    }
}

特点:

  • 支持holder链式调用。
  • 只需实现onBind方法,对数据和视图进行绑定。
  • 多布局支持,可以在构造方法中实现RLItemViewType接口,或者构造Type传null,然后在Adapter内部实现RLItemViewType接口,多种选择。
  • 为了满足实际网络请求案例,支持在构造函数Data传null,然后网络数据返回时,调用BaseAdapter.setData()方法刷新数据,在刷新控件的支持下,加载更多时调用BaseAdapter.addAll()。

适配器实现代码:

public abstract class BaseAdapter<T> extends RecyclerView.Adapter<ViewHolder> implements AdapterInterFace<T> {
    private List<T> mData;
    private int layoutId;
    protected Context mContext;
    private RLItemViewType<T> itemViewType;
    private OnItemClickListener mOnItemClickListener;
    private OnItemLongClickListener mOnItemLongClickListener;

    /**
     * 单布局构造
     */
    public BaseAdapter(Context context, List<T> mDatas, int layoutId) {
        this.mContext = context;
        this.mData = mDatas;
        if (this.mData == null) {
            this.mData = new ArrayList<>();
        }
        this.layoutId = layoutId;
        this.itemViewType = null;
    }

    /**
     * 多布局构造
     */
    public BaseAdapter(Context context, List<T> mDatas, RLItemViewType<T> viewType) {
        this.mContext = context;
        this.mData = mDatas;
        if (this.mData == null) {
            this.mData = new ArrayList<>();
        }
        this.itemViewType = viewType == null ? createViewType() : viewType;
        if (itemViewType == null) {
            //使用这个构造函数,你必须实现RLItemViewType接口。
            new NullPointerException("NullPointerException  With this constructor, you must implement the RLItemViewType interface.");
        }
    }

    /**
     * 如果多布局未在构造中指定Type时,需要在内部实现此方法
     */
    protected RLItemViewType<T> createViewType() {
        return null;
    }


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
        //加载指定item布局
        View inflate = LayoutInflater.from(mContext).inflate(itemViewType == null ?
                layoutId : itemViewType.getLayoutId(viewType), parent, false);
        final ViewHolder holder = new ViewHolder(inflate);
        //用户需要监听时,才设置监听事件
        if (mOnItemClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mOnItemClickListener.onItemClick(v, viewType, holder.getAdapterPosition());
                }
            });
        }
        if (mOnItemLongClickListener != null) {
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    mOnItemLongClickListener.onItemLongClick(v, viewType, holder.getAdapterPosition());
                    return true;
                }
            });
        }
        return holder;
    }

    @Override
    public final void onBindViewHolder(ViewHolder holder, int position) {
        onBind(holder, position, mData.get(position));
    }

    @Override
    public int getItemCount() {
        return mData == null || mData.size() <= 0 ? 0 : mData.size();
    }

    public void setmOnItemClickListener(OnItemClickListener mOnItemClickListener) {
        this.mOnItemClickListener = mOnItemClickListener;
    }

    public void setmOnItemLongClickListener(OnItemLongClickListener mOnItemLongClickListener) {
        this.mOnItemLongClickListener = mOnItemLongClickListener;
    }

    @Override
    public void addAll(List<T> data) {
        mData.addAll(data);
        notifyDataSetChanged();
    }

    @Override
    public void setData(List<T> data) {
        mData = data;
        notifyDataSetChanged();
    }

    @Override
    public List<T> getData() {
        return mData;
    }

    /**
     * 绑定数据操作
     */
    public abstract void onBind(ViewHolder holder, int position, T item);
}

多布局接口定义:

public interface RLItemViewType<T> {

    int getItemViewType(int position, T t);


    @LayoutRes
    int getLayoutId(int viewType);
}

适配器接口定义:

public interface AdapterInterFace<T> {

    void addAll(List<T> data);

    void setData(List<T> data);

    List<T> getData();
}

适配器监听接口定义:

public interface OnItemClickListener {
    void onItemClick(View itemView, int viewType, int position);
}
public interface OnItemLongClickListener {
    void onItemLongClick(View itemView, int viewType, int position);
}

ViewHolder实现代码:

public class ViewHolder extends RecyclerView.ViewHolder {

    /**
     * 在put数据之前,会先查找要put的数据是否已经存在,如果存在就是修改,不存在就添加。
     */
    private SparseArray<View> childViews = new SparseArray<>();

    private View view;

    public ViewHolder(View itemView) {
        super(itemView);
    }

    @Deprecated
    public <T extends View> T getView(int id) {
        return findViewById(id);
    }

    @SuppressWarnings("unchecked")
    public <T extends View> T findViewById(int id) {
        View childView = childViews.get(id);
        if (childView == null) {
            childView = itemView.findViewById(id);
            if (childView != null) {
                childViews.put(id, childView);
            }
        }
        view = childView;
        return (T) childView;
    }


//    public ExtendViewHolder view(int viewId) {
//        return ExtendViewHolder.getInstance(this, findViewById(viewId));
//    }

    public ViewHolder view(int viewId) {
        findViewById(viewId);
        return this;
    }


    public ViewHolder setTag(Object tag) {
        view.setTag(tag);
        return this;
    }

    public ViewHolder setOnClickListener(View.OnClickListener listener) {
        view.setOnClickListener(listener);
        return this;
    }


    public ViewHolder setBackground(Drawable background) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            view.setBackground(background);
        }
        return this;
    }

    public ViewHolder setBackgroundColor(@ColorInt int color) {
        view.setBackgroundColor(color);
        return this;
    }

    public ViewHolder setBackgroundResource(@DrawableRes int resid) {
        view.setBackgroundResource(resid);
        return this;
    }

    public ViewHolder setScaleType(ImageView.ScaleType scaleType) {
        if (view instanceof ImageView) {
            ((ImageView) view).setScaleType(scaleType);
        }
        return this;
    }

    public ViewHolder setText(CharSequence text) {
        if (view instanceof TextView) {//Button、EditText等控件继承自TextView
            ((TextView) view).setText(text);
        }
        return this;
    }

    public ViewHolder setText(int viewId, CharSequence text) {
        View findView = findViewById(viewId);
        if (findView instanceof TextView) {//Button、EditText等控件继承自TextView
            ((TextView) findView).setText(text);
        }
        return this;
    }

    public ViewHolder setTextColor(@ColorInt int color) {
        if (view instanceof TextView) {
            ((TextView) view).setTextColor(color);
        }
        return this;
    }

    public ViewHolder setTextSize(float size) {
        if (view instanceof TextView) {
            ((TextView) view).setTextSize(size);
        }
        return this;
    }
}

源码地址:https://github.com/zhangzhichaolove/BasicsFrame

相关文章

网友评论

      本文标题:一步一步手撸Android通用框架 (五)

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