package com.android.app_base.base.adapter;
|
|
import android.content.Context;
|
import android.util.SparseArray;
|
import android.view.LayoutInflater;
|
import android.view.View;
|
import android.view.ViewGroup;
|
|
import androidx.annotation.IdRes;
|
import androidx.annotation.IntRange;
|
import androidx.annotation.NonNull;
|
import androidx.annotation.Nullable;
|
import androidx.databinding.DataBindingUtil;
|
import androidx.databinding.ViewDataBinding;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.RecyclerView;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
|
/**
|
* @author Ljj
|
* @date 2023.03.02. 17:09
|
* @desc RecyclerView 适配器基类
|
*/
|
public abstract class BaseRVAdapter<T,VDB extends ViewDataBinding,VH extends BaseRVAdapter.BaseViewHolder<VDB>> extends RecyclerView.Adapter<VH> {
|
|
/** 上下文对象 */
|
protected final Context mContext;
|
|
/** RecyclerView 对象 */
|
protected RecyclerView mRecyclerView;
|
|
/** 条目点击监听器 */
|
protected OnItemClickListener mItemClickListener;
|
/** 条目长按监听器 */
|
protected OnItemLongClickListener mItemLongClickListener;
|
/**
|
* 该 adapter 上绑定的滑动监听器
|
*/
|
protected MyOnScrollListener myOnScrollListener;
|
|
/** 条目子 View 点击监听器 */
|
protected SparseArray<OnChildClickListener> mChildClickListeners;
|
/** 条目子 View 长按监听器 */
|
protected SparseArray<OnChildLongClickListener> mChildLongClickListeners;
|
/**
|
* 列表数据
|
*/
|
protected List<T> mDataList;
|
|
public BaseRVAdapter(Context context) {
|
mContext = context;
|
if (mContext == null) {
|
throw new IllegalArgumentException("are you ok?");
|
}
|
}
|
|
public BaseRVAdapter(Context context, List<T> list) {
|
mContext = context;
|
mDataList = (list == null) ? new ArrayList<T>() : list;
|
setData(list);
|
}
|
|
|
@NonNull
|
@Override
|
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
VDB itemBind = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()),getLayoutId(),parent,false);
|
return getViewHolder(itemBind,viewType);
|
}
|
|
protected abstract int getLayoutId();
|
protected abstract void onBind(VH holder, int position);
|
protected abstract VH getViewHolder(VDB itemBind,int viewType);
|
|
@Override
|
public void onBindViewHolder(@NonNull VH holder, int position) {
|
View itemView = holder.itemView;
|
// 设置条目的点击和长按事件
|
if (mItemClickListener != null) {
|
itemView.setOnClickListener(new View.OnClickListener() {
|
@Override
|
public void onClick(View view) {
|
mItemClickListener.onItemClick(mRecyclerView,view, holder.getLayoutPosition());
|
}
|
});
|
}
|
if (mItemLongClickListener != null) {
|
itemView.setOnLongClickListener(new View.OnLongClickListener() {
|
@Override
|
public boolean onLongClick(View view) {
|
return mItemLongClickListener.onItemLongClick(mRecyclerView, view, holder.getLayoutPosition());
|
}
|
});
|
}
|
|
// 设置条目子 View 点击事件
|
if (mChildClickListeners != null) {
|
for (int i = 0; i < mChildClickListeners.size(); i++) {
|
View childView = itemView.findViewById(mChildClickListeners.keyAt(i));
|
if (childView != null) {
|
childView.setOnClickListener(new View.OnClickListener() {
|
@Override
|
public void onClick(View view) {
|
OnChildClickListener listener = mChildClickListeners.get(view.getId());
|
if (listener != null) {
|
listener.onChildClick(mRecyclerView, view, holder.getLayoutPosition());
|
}
|
}
|
});
|
}
|
}
|
}
|
|
// 设置条目子 View 长按事件
|
if (mChildLongClickListeners != null) {
|
for (int i = 0; i < mChildLongClickListeners.size(); i++) {
|
View childView = itemView.findViewById(mChildLongClickListeners.keyAt(i));
|
if (childView != null) {
|
childView.setOnLongClickListener(new View.OnLongClickListener() {
|
@Override
|
public boolean onLongClick(View view) {
|
OnChildLongClickListener listener = mChildLongClickListeners.get(view.getId());
|
if (listener != null) {
|
return listener.onChildLongClick(mRecyclerView, view, holder.getLayoutPosition());
|
}
|
return false;
|
}
|
});
|
}
|
}
|
}
|
onBind(holder,position);
|
}
|
|
|
@Override
|
public int getItemCount() {
|
return mDataList == null ? 0 : mDataList.size();
|
}
|
|
@Override
|
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
|
mRecyclerView = recyclerView;
|
// 用户设置了滚动监听,需要给 RecyclerView 设置监听
|
if (myOnScrollListener != null) {
|
// 添加滚动监听
|
mRecyclerView.addOnScrollListener(myOnScrollListener);
|
}
|
// 判断当前的布局管理器是否为空,如果为空则设置默认的布局管理器
|
if (mRecyclerView.getLayoutManager() == null) {
|
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mContext);;
|
mRecyclerView.setLayoutManager(layoutManager);
|
}
|
}
|
|
@Override
|
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
|
// 移除滚动监听
|
if (myOnScrollListener != null) {
|
mRecyclerView.removeOnScrollListener(myOnScrollListener);
|
}
|
mRecyclerView = null;
|
}
|
|
public RecyclerView getRecyclerView() {
|
return mRecyclerView;
|
}
|
|
/**
|
* 自定义ViewHolder,基类
|
* @param <VDB>
|
*/
|
public static class BaseViewHolder<VDB extends ViewDataBinding> extends RecyclerView.ViewHolder{
|
protected VDB binding;
|
public BaseViewHolder(@NonNull View itemView) {
|
super(itemView);
|
|
}
|
public BaseViewHolder(VDB binding) {
|
this(binding.getRoot());
|
this.binding = binding;
|
}
|
|
public VDB getBinding() {
|
return binding;
|
}
|
}
|
/**
|
* 设置新的数据
|
*/
|
public void setData(@Nullable List<T> data) {
|
mDataList = data;
|
notifyDataSetChanged();
|
}
|
/**
|
* 获取当前数据
|
*/
|
@Nullable
|
public List<T> getData() {
|
return mDataList;
|
}
|
/**
|
* 追加一些数据
|
*/
|
public void addData(List<T> data) {
|
if (data == null || data.size() == 0) {
|
return;
|
}
|
|
if (mDataList == null || mDataList.size() == 0) {
|
setData(data);
|
} else {
|
//一个一个的添加
|
for (T datum : data) {
|
addItem(datum);
|
}
|
}
|
}
|
/**
|
* 从头部 追加一些数据
|
*/
|
public void addDataFromHead(List<T> data) {
|
if (data == null || data.size() == 0) {
|
return;
|
}
|
|
if (mDataList == null || mDataList.size() == 0) {
|
setData(data);
|
} else {
|
mDataList.addAll(0, data);
|
notifyDataSetChanged();
|
}
|
}
|
/**
|
* 清空当前数据
|
*/
|
public void clearData() {
|
if (mDataList == null || mDataList.size() == 0) {
|
return;
|
}
|
mDataList.clear();
|
notifyDataSetChanged();
|
}
|
/**
|
* 获取某个位置上的数据
|
*/
|
public T getItem(@IntRange(from = 0) int position) {
|
return mDataList.get(position);
|
}
|
|
/**
|
* 更新某个位置上的数据
|
*/
|
public void setItem(@IntRange(from = 0) int position, @NonNull T item) {
|
if (mDataList == null) {
|
mDataList = new ArrayList<>();
|
}
|
mDataList.set(position, item);
|
notifyItemChanged(position);
|
}
|
/**
|
* 添加单条数据
|
*/
|
public void addItem(@NonNull T item) {
|
if (mDataList == null) {
|
mDataList = new ArrayList<>();
|
}
|
|
addItem(mDataList.size(), item);
|
}
|
|
public void addItem(@IntRange(from = 0) int position, @NonNull T item) {
|
if (mDataList == null) {
|
mDataList = new ArrayList<>();
|
}
|
|
if (position < mDataList.size()) {
|
mDataList.add(position, item);
|
} else {
|
mDataList.add(item);
|
position = mDataList.size() - 1;
|
}
|
notifyItemInserted(position);
|
}
|
/**
|
* 删除单条数据
|
*/
|
public void removeItem(@NonNull T item) {
|
int index = mDataList.indexOf(item);
|
if (index != -1) {
|
removeItem(index);
|
}
|
}
|
public void removeItem(@IntRange(from = 0) int position) {
|
// 如果是在for循环删除后要记得i--
|
mDataList.remove(position);
|
// 告诉适配器删除数据的位置,会有动画效果
|
notifyItemRemoved(position);
|
}
|
/**
|
* 设置 RecyclerView 条目点击监听
|
*/
|
public void setOnItemClickListener(OnItemClickListener listener) {
|
checkRecyclerViewState();
|
mItemClickListener = listener;
|
}
|
|
/**
|
* 设置 RecyclerView 条目子 View 点击监听
|
*/
|
public void setOnChildClickListener(@IdRes int id, OnChildClickListener listener) {
|
checkRecyclerViewState();
|
if (mChildClickListeners == null) {
|
mChildClickListeners = new SparseArray<>();
|
}
|
mChildClickListeners.put(id, listener);
|
}
|
|
/**
|
* 设置RecyclerView条目长按监听
|
*/
|
public void setOnItemLongClickListener(OnItemLongClickListener listener) {
|
checkRecyclerViewState();
|
mItemLongClickListener = listener;
|
}
|
|
/**
|
* 设置 RecyclerView 条目子 View 长按监听
|
*/
|
public void setOnChildLongClickListener(@IdRes int id, OnChildLongClickListener listener) {
|
checkRecyclerViewState();
|
if (mChildLongClickListeners == null) {
|
mChildLongClickListeners = new SparseArray<>();
|
}
|
mChildLongClickListeners.put(id, listener);
|
}
|
|
private void checkRecyclerViewState() {
|
if (mRecyclerView != null) {
|
// 必须在 RecyclerView.setAdapter() 之前设置监听
|
throw new IllegalStateException("are you ok?");
|
}
|
}
|
/**
|
* 设置 RecyclerView 条目滚动监听
|
*/
|
public void setOnScrollingListener(OnScrollingListener listener) {
|
/** RecyclerView 滚动事件监听 */
|
//如果当前已经有设置滚动监听,再次设置需要移除原有的监听器
|
if (myOnScrollListener == null) {
|
myOnScrollListener = new MyOnScrollListener(listener);
|
} else {
|
mRecyclerView.removeOnScrollListener(myOnScrollListener);
|
}
|
//用户设置了滚动监听,需要给RecyclerView设置监听
|
//用户设置了滚动监听,需要给RecyclerView设置监听
|
if (mRecyclerView != null) {
|
//添加滚动监听
|
mRecyclerView.addOnScrollListener(new MyOnScrollListener(listener));
|
}
|
}
|
|
|
/**
|
* RecyclerView 条目点击监听类
|
*/
|
public interface OnItemClickListener{
|
|
/**
|
* 当 RecyclerView 某个条目被点击时回调
|
*
|
* @param recyclerView RecyclerView 对象
|
* @param itemView 被点击的条目对象
|
* @param position 被点击的条目位置
|
*/
|
void onItemClick(RecyclerView recyclerView, View itemView, int position);
|
}
|
|
/**
|
* RecyclerView 条目长按监听类
|
*/
|
public interface OnItemLongClickListener {
|
|
/**
|
* 当 RecyclerView 某个条目被长按时回调
|
*
|
* @param recyclerView RecyclerView 对象
|
* @param itemView 被点击的条目对象
|
* @param position 被点击的条目位置
|
* @return 是否拦截事件
|
*/
|
boolean onItemLongClick(RecyclerView recyclerView, View itemView, int position);
|
}
|
|
/**
|
* RecyclerView 条目子 View 点击监听类
|
*/
|
public interface OnChildClickListener {
|
|
/**
|
* 当 RecyclerView 某个条目 子 View 被点击时回调
|
*
|
* @param recyclerView RecyclerView 对象
|
* @param childView 被点击的条目子 View
|
* @param position 被点击的条目位置
|
*/
|
void onChildClick(RecyclerView recyclerView, View childView, int position);
|
}
|
|
/**
|
* RecyclerView 条目子 View 长按监听类
|
*/
|
public interface OnChildLongClickListener {
|
|
/**
|
* 当 RecyclerView 某个条目子 View 被长按时回调
|
*
|
* @param recyclerView RecyclerView 对象
|
* @param childView 被点击的条目子 View
|
* @param position 被点击的条目位置
|
*/
|
boolean onChildLongClick(RecyclerView recyclerView, View childView, int position);
|
}
|
/**
|
* RecyclerView 滚动监听接口
|
*/
|
public interface OnScrollingListener {
|
|
/**
|
* 列表滚动到最顶部
|
*
|
* @param recyclerView RecyclerView 对象
|
*/
|
void onScrollTop(RecyclerView recyclerView);
|
|
/**
|
* 列表滚动中
|
*
|
* @param recyclerView RecyclerView 对象
|
*/
|
void onScrolling(RecyclerView recyclerView);
|
|
/**
|
* 列表滚动到最底部
|
*
|
* @param recyclerView RecyclerView 对象
|
*/
|
void onScrollDown(RecyclerView recyclerView);
|
}
|
|
/**
|
* 自定义RecyclerView的滑动监听器
|
*/
|
public static class MyOnScrollListener extends RecyclerView.OnScrollListener {
|
private OnScrollingListener onScrollingListener;
|
MyOnScrollListener(OnScrollingListener onScrollingListener){
|
this.onScrollingListener = onScrollingListener;
|
}
|
@Override
|
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
|
if (onScrollingListener == null) {
|
return;
|
}
|
|
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
|
|
if (!recyclerView.canScrollVertically(1)) {
|
// 已经到底了
|
onScrollingListener.onScrollDown(recyclerView);
|
} else if (!recyclerView.canScrollVertically(-1)) {
|
// 已经到顶了
|
onScrollingListener.onScrollTop(recyclerView);
|
}
|
|
} else if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
|
// 正在滚动中
|
onScrollingListener.onScrolling(recyclerView);
|
}
|
}
|
}
|
}
|