Android技术知识

RecyclerView 通用 Adapter

2018-08-31  本文已影响3人  stefanJi

先看使用方法 👀

Step 1. Add the JitPack repository to your build file

Add it in your root build.gradle at the end of repositories:

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Step 2. Add the dependency

dependencies {
    implementation 'com.github.stefanji:CommRecyclerViewAdapter:2.1'
}

Use Simple

Kotlin:

listView.adapter = object : CommRecyclerViewAdapter<String>(strings, object : AdapterItem {

            lateinit var textView: TextView
        
            override fun bindViews(p: View) {
                textView = p.findViewById(android.R.id.text1)
            }

            override fun handleData(p: Int) {
                val s = strings[p]
                textView.text = s
            }

            override fun getResId(): Int {
                return android.R.layout.simple_list_item_1
            }
        }) {}

Java:

CommRecyclerViewAdapter<String> mAdapter = new CommRecyclerViewAdapter<>(strings, new AdapterItem() {
    TextView title;

    @Override
    public void handleData(int position) {
        String s = strings.get(position);
        title.setText(s);
    }

    @Override
    public int getResId() {
        return R.layout.list_item;
    }

    @Override
    public void bindViews(View itemView) {
        title = itemView.findViewById(R.id.strTitle);
    }
});
rcv.setAdapter(mAdapter);
rcv.setLayoutManager(ew LinearLayoutManager(context));

再看原理

// 继承 RecyclerView.Adapter
// 提取一层 CommItemHolder,其持有 AdapterItem
//   在 onCreateViewHolder 时,将 adapterItem 注入
//   在 onBindViewHolder 时,通过 CommItemHolder 获取 adapterItem,实现 handleData
public class CommRecyclerViewAdapter<T> extends RecyclerView.Adapter<CommItemHolder> {

    private AdapterItem mAdapterItem;

     public CommRecyclerViewAdapter(List<T> data, AdapterItem adapterItem) {
        this.mData = mData;
        this.mAdapterItem = adapterItem;
    }

    public CommRecyclerViewAdapter(T[] arrayData, AdapterItem adapterItem) {
        this.mArrayData = arrayData;
        this.mAdapterItem = adapterItem;
    }

    public CommItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new CommItemHolder(parent.getContext(), parent, mAdapterItem);
    }

    public void onBindViewHolder(CommItemHolder holder, int position) {
        // 通过 tag 存储 position,方便 clickListener
        holder.itemView.setTag(position);
        holder.itemView.setOnClickListener(this);
        holder.itemView.setOnLongClickListener(this);
        holder.mAdapterItem.handleData(position);
    }

    public void onClick(View view) {
        int position = (int) view.getTag();
        if (clickListener != null) {
            clickListener.onClickItem(position);
        }
    }

    public boolean onLongClick(View view) {
        int position = (int) view.getTag();
        if (longClickListener != null) {
            longClickListener.onLongClickItem(position);
            return true;
        }
        return false;
    }
}

AdapterItem:定义3个需实现的方法

public interface AdapterItem {
    // 数据渲染到视图
    // position 当前 item 位置
    void handleData(int position);
    
    // 需返回布局 id
    int getResId();

    // 这里面做视图的 itemView.findViewById
    void bindViews(View itemView);
}

CommItemHolder:
通过在构造方法中 super 中加载布局,然后调 adapterItem.bindViews 将加载的布局返回。利用了 RecyclerView.ViewHolder 内部存有的 itemView 对象

public class CommItemHolder extends RecyclerView.ViewHolder {
    AdapterItem mAdapterItem;

    CommItemHolder(Context context, ViewGroup parent, AdapterItem adapterItem) {
        super(LayoutInflater.from(context).inflate(adapterItem.getResId(), parent, false));
        mAdapterItem = adapterItem;
        mAdapterItem.bindViews(this.itemView);
    }
}
上一篇下一篇

猜你喜欢

热点阅读