如何正确的写一个简单的Adapter ---- CommonRecyclerAdapter

372 阅读3分钟

适用范围

一般简单的RecycleView Adapter请统一使用CommonRecyclerAdapter,如果你需要做瀑布流,item的样式多种多样,请使用XXXXX。

CommonRecyclerAdapter.java

好处

  • 风格统一
  • 逻辑清晰,没有多余的代码
  • 搭配一键生成模板,实现快速开发,不需要花时间写重复的代码

先看示例代码如下:

TestActivity.java

package com.okaynaira.android.ui.activity;

import android.content.Context;
import android.view.View;

import com.okaynaira.android.R;
import com.okaynaira.android.databinding.ItemTestBinding;

import leo.work.support.base.adapter.CommonRecyclerAdapter;
import leo.work.support.base.adapter.CommonRecyclerViewHolder;

/**
 * ---------------------------------------------------------------------------------------------
 * 功能描述:
 * ---------------------------------------------------------------------------------------------
 * 时  间: 2021/12/21
 * ---------------------------------------------------------------------------------------------
 * 代码创建: 1613-3
 * ---------------------------------------------------------------------------------------------
 * 代码备注:
 * ---------------------------------------------------------------------------------------------
 **/
public class TestAdapter extends CommonRecyclerAdapter<String, TestAdapter.TestAdapterHolder, ItemTestBinding, TestAdapter.OnTestAdapterCallBack> {

    public TestAdapter(Context context, OnTestAdapterCallBack callBack) {
        super(context, callBack);
    }

    @Override
    protected int setLayout() {
        return R.layout.item_test;
    }

    @Override
    protected TestAdapterHolder setViewHolder(ItemTestBinding binding, OnTestAdapterCallBack callBack) {
        return new TestAdapterHolder(binding, callBack);
    }


    static class TestAdapterHolder extends CommonRecyclerViewHolder<String, ItemTestBinding, OnTestAdapterCallBack> {

        public TestAdapterHolder(ItemTestBinding binding, OnTestAdapterCallBack callBack) {
            super(binding, callBack);
        }

        //初始化View
        @Override
        protected void initView(int position, String model) {
            binding.tvName.setText(model);
        }

        //初始化监听
        @Override
        protected void initListener(int position, String model) {
            binding.tvName.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    callBack.onClickItem(position);
                }
            });
        }
    }

    public interface OnTestAdapterCallBack {

        void onClickItem(int position);
    }
}

CommonRecyclerAdapter.java

package leo.work.support.base.adapter;

import android.content.Context;

import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.recyclerview.widget.RecyclerView;

import android.view.LayoutInflater;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;


/**
 * ---------------------------------------------------------------------------------------------
 * 功能描述: 简单的RecyclerView Adapter
 * ---------------------------------------------------------------------------------------------
 * 时  间: 2018/3/4.
 * ---------------------------------------------------------------------------------------------
 * 代码创建: 刘桂安
 * ---------------------------------------------------------------------------------------------
 * 备  注:
 * ---------------------------------------------------------------------------------------------
 **/

public abstract class CommonRecyclerAdapter<M, H extends CommonRecyclerViewHolder, B extends ViewDataBinding, C> extends RecyclerView.Adapter {

    public Context context;
    public LayoutInflater mInflater;
    public List<M> mList;
    public C callBack;

    public CommonRecyclerAdapter(Context context, C callBack) {
        this.context = context;
        this.mInflater = LayoutInflater.from(this.context);
        this.mList = new ArrayList<>();
        this.callBack = callBack;
    }

    @Override
    public int getItemCount() {
        if (mList == null) {
            return 0;
        }
        return mList.size();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        int layout = setLayout();
        B binding = DataBindingUtil.inflate(mInflater, layout, parent, false);
        return setViewHolder(binding, callBack);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
        H viewHolder = (H) holder;
        viewHolder.initView(position, mList.get(position));
        viewHolder.initListener(position, mList.get(position));
    }

    protected abstract int setLayout();

    protected abstract H setViewHolder(B binding, C callBack);

}

CommonRecyclerAdapter讲解

  • CommonMVPActivity继承RecyclerView.Adapter,本质上就是一个普通的Adapter。我们通过abstract封装的方式达到快速开发,风格统一,增加可读性的目的。

  • CommonMVPActivity主要持有了两个个对象,也提供context和mInflater。

    • mList ----> 数据
    • callBack ----> 回调接口,主要用于相应各种事件
  • onBindViewHolder调用了ViewHolder的initView(),initListener()方法,请勿在Adapter内写UI操作,所有的UI操作(设置文字,背景,颜色,显示隐藏,点击事件...)请在ViewHolder的initView(),initListener()方法中写。

  • 请不要再Adapter,ViewHolder中修改mList的数据,只能够获取mList的数据.

  • 增,删,改mList,请通过callBack告知使用者(Activity,Fragment等...)在外部修改。

  • 也不要在Adapter,ViewHolder中做数据库修改,网络请求等逻辑。

  • 让Adapter保持单纯,只做获取并展示数据,通过callBack告知使用者事件,这两个操作。

CommonRecyclerViewHolder.java

package leo.work.support.base.adapter;

import android.content.Context;

import androidx.databinding.ViewDataBinding;
import androidx.recyclerview.widget.RecyclerView;

/**
 * ---------------------------------------------------------------------------------------------
 * 功能描述:
 * ---------------------------------------------------------------------------------------------
 * 时  间: 2021/12/21
 * ---------------------------------------------------------------------------------------------
 * 代码创建: 1613-3
 * ---------------------------------------------------------------------------------------------
 * 代码备注:
 * ---------------------------------------------------------------------------------------------
 **/
public abstract class CommonRecyclerViewHolder<M, B extends ViewDataBinding, C> extends RecyclerView.ViewHolder {

    public B binding;
    public C callBack;
    public Context context;

    public CommonRecyclerViewHolder(Context context, B binding, C callBack) {
        super(binding.getRoot());
        this.context = context;
        this.binding = binding;
        this.callBack = callBack;
    }

    protected abstract void initView(int position, M model);

    protected abstract void initListener(int position, M model);
}

CommonRecyclerViewHolder讲解

  • CommonRecyclerViewHolder继承RecyclerView.ViewHolder,本质上就是一个普通的ViewHolder。
  • CommonRecyclerViewHolder主要持有了两个个对象,也提供context。
    • binding ----> ViewDataBinding 所有的View都在这里,你不再需要findViewById。不懂可以看官方文档
    • callBack ----> 回调接口,主要用于相应各种事件
  • initView() ----> 初始化View,在Adapter的onBindViewHolder方法中被执行一次
  • initListener() ----> 初始化监听事件,在Adapter的onBindViewHolder方法中被执行一次

快速生成CommonRecyclerAdapter的模板

  • 设置方式:

    设置模板 image.png 使用模板 image.png
  • 模板内容:

    #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
    
    import android.content.Context;
    import android.view.View;
    
    import leo.work.support.base.adapter.CommonRecyclerAdapter;
    
    #parse("File Header.java")
    public class ${NAME} extends CommonRecyclerAdapter<String, ${NAME}.${NAME}Holder,#if (${BINDING_NAME} && ${BINDING_NAME} != "") ${BINDING_NAME} #else Item(xxxBinding)#end, ${NAME}.On${NAME}CallBack> {
    
    
        public ${NAME}(Context context, On${NAME}CallBack callBack) {
            super(context, callBack);
        }
    
        @Override
        protected int setLayout() {
            return R.layout#if (${LAYOUT_NAME} && ${LAYOUT_NAME} != "").${LAYOUT_NAME} #else.item_#end;
        }
    
        @Override
        protected ${NAME}Holder setViewHolder#if (${BINDING_NAME} && ${BINDING_NAME} != "")(${BINDING_NAME} #else(Item(xxxBinding)#end binding, On${NAME}CallBack callBack) {
            return new ${NAME}Holder(context, binding, callBack);
        }
    
    
        static class ${NAME}Holder extends CommonRecyclerViewHolder<String,#if (${BINDING_NAME} && ${BINDING_NAME} != "") ${BINDING_NAME} #else Item(xxxBinding)#end, ${NAME}.On${NAME}CallBack> {
    
            public ${NAME}Holder(Context context,#if (${BINDING_NAME} && ${BINDING_NAME} != "") ${BINDING_NAME} #else Item(xxxBinding)#end binding, On${NAME}CallBack callBack) {
                super(context, binding, callBack);
            }
    
            @Override
            protected void initView(int position, String model) {
    
            }
    
            @Override
            protected void initListener(int position, String model) {
    
            }
        }
    
        public interface On${NAME}CallBack {
    
        }
    }
    

快速设置RecyclerView

  • 设置模板

    image.png

    image.png 你只需要输入initR..就可以快速初始化 image.png

  • 模板内容:

$adapter$ adapter = new $adapter$(activity, this);
RecyclerSupport.setLinearLayoutManager(activity, binding.$RecyclerView$);
binding.$RecyclerView$.setAdapter(adapter);