Step by step Android general framework (5)

Posted by pyro3k on Sat, 04 Apr 2020 06:55:02 +0200

At present, RecyclerView is used in more and more projects. In such a high-frequency use scenario, we should try to carry out secondary encapsulation, which will reduce our large amount of code.

Demonstration:

  • new anonymous internal method:
        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);
            }
        });
  • How objects are inherited:
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);
    }
}

Characteristic:

  • Support holder chain call.
  • Just implement the onBind method to bind data and view.
  • Multi layout support. You can implement the RLItemViewType interface in the construction method, or pass null to the construction Type, and then implement the RLItemViewType interface in the Adapter. There are many options.
  • In order to meet the actual network request cases, it is supported to call BaseAdapter.setData() method to refresh the Data when the constructor Data is passed to null, and then when the network Data is returned, and BaseAdapter.addAll() method is called when loading more under the support of refresh control.

Adapter implementation code:

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;

    /**
     * Single layout construction
     */
    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;
    }

    /**
     * Multi layout construction
     */
    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) {
            //Using this constructor, you must implement the RLItemViewType interface.
            new NullPointerException("NullPointerException  With this constructor, you must implement the RLItemViewType interface.");
        }
    }

    /**
     * This method needs to be implemented internally if the multi layout does not specify a Type in the construct
     */
    protected RLItemViewType<T> createViewType() {
        return null;
    }


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
        //Load the specified item layout
        View inflate = LayoutInflater.from(mContext).inflate(itemViewType == null ?
                layoutId : itemViewType.getLayoutId(viewType), parent, false);
        final ViewHolder holder = new ViewHolder(inflate);
        //Set the listening event only when the user needs to listen
        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;
    }

    /**
     * Bind data operation
     */
    public abstract void onBind(ViewHolder holder, int position, T item);
}

Multi layout interface definition:

public interface RLItemViewType<T> {

    int getItemViewType(int position, T t);


    @LayoutRes
    int getLayoutId(int viewType);
}

Adapter interface definition:

public interface AdapterInterFace<T> {

    void addAll(List<T> data);

    void setData(List<T> data);

    List<T> getData();
}

Adapter listening interface definition:

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

ViewHolder implementation code:

public class ViewHolder extends RecyclerView.ViewHolder {

    /**
     * Before putting data, it will find out whether the data to put already exists. If it exists, it will be modified. If it does not exist, it will be added.
     */
    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) {//Controls such as Button and EditText inherit from TextView
            ((TextView) view).setText(text);
        }
        return this;
    }

    public ViewHolder setText(int viewId, CharSequence text) {
        View findView = findViewById(viewId);
        if (findView instanceof TextView) {//Controls such as Button and EditText inherit from 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;
    }
}

Source address: https://github.com/zhangzhichaolove/BasicsFrame

Topics: network github