通用的RecyclerView 的Adapter
因为在项目中很多的地方用到RecyclerView 并且每次使用的时候都要写一个适配器,我特(>ω<)喵的这么懒得人能忍?所以查了很多通用适配器的资料看了为RecyclerView打造通用Adapter 让RecyclerView更加好用
这篇文章完成了自定义的适配器
package cn.song.news.base;
import android.content.Context;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.support.v4.util.SparseArrayCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Song on 2019/4/10 18:18
* Happy Code
*/
public abstract class BaseRecyclerViewAdapter<T> extends RecyclerView.Adapter<BaseRecyclerViewAdapter.ViewHolder> {
Context mContext;
List<T> mDataList;
@LayoutRes
int resourceID;
public BaseRecyclerViewAdapter(Context context, List<T> dataList, @LayoutRes int resourceID) {
mContext = context;
mDataList = dataList;
this.resourceID = resourceID;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(resourceID, parent, false);
return new ViewHolder(view);
}
/**
* !!!这个方法中的参数列表中的ViewHolder 一定要和 上面extends RecyclerView.Adapter<> "<>"中的一样,直接复制过来
* 不然可能报没有覆盖抽象方法这个错误
*/
@Override
public void onBindViewHolder(BaseRecyclerViewAdapter.ViewHolder holder, int position) {
bindViewHolder(holder, mDataList.get(position));
}
@Override
public int getItemCount() {
return mDataList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
SparseArrayCompat<View> mViews = new SparseArrayCompat<>();
public ViewHolder(View itemView) {
super(itemView);
}
public View getView(@IdRes int idRes) {
View v = mViews.get(idRes);
if (v == null) {
v = itemView.findViewById(idRes);
mViews.put(idRes, v);
}
return v;
}
public ViewHolder setItemListener(View.OnClickListener listener) {
itemView.setOnClickListener(listener);
return this;
}
}
public abstract void bindViewHolder(ViewHolder holder, T itemBean);
}
使用时候
RecyclerView.setAdapter(new BaseRecyclerViewAdapter<OneBean>(getActivity(), beanList, R.layout.rv_one) {
@Override
public void bindViewHolder(final ViewHolder holder, final OneBean itemBean) {
String str = clickedMap.get(holder.getAdapterPosition());
if(!TextUtils.isEmpty(str) && str.equals("1")){
//这里可以优化到适配器中,对应不同的View 只需要传入资源id 和 要设置的东西就好了。
((TextView) holder.getView(R.id.tv_one)).setText("I'm clicked. 重新赋值 "+holder.getAdapterPosition());
}else {
((TextView) holder.getView(R.id.tv_one)).setText(itemBean.getName());
}
holder.setItemListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String str = ((TextView) holder.getView(R.id.tv_one)).getText().toString();
Log.e(FragmentOne.class.getSimpleName(), "onClick: " + str + holder.getAdapterPosition()+"Address:"+((TextView) holder.getView(R.id.tv_one)));
((TextView) holder.getView(R.id.tv_one)).setText( "I'm clicked.");
clickedMap.put(holder.getAdapterPosition(),"1");
Toast.makeText(getActivity(), "" + ((TextView) holder.getView(R.id.tv_one)).getText(), Toast.LENGTH_SHORT).show();
}
});
}
});
上面使用的时候,我点击Item 后改变TextView 的文字,但是在上划和下划时候,因为View 复用的关系,每个点击后的TextView 又被改变回去了,所以再上面使用的时候加入了Map<Integer,String> clickedMap=new HashMap<>();
来判断这个Item 是否被点击过了,然后在重新显示Item 的时候在Map 里判断是否存在被点击过的Item 的ID(就是第几个Item),如果存在就初始化成被点击后的状态就可以了