Android-RecyclerView通用适配器BaseAda
之前也是搞了一版MonkeyLei:Android-RecyclerView通用适配器BaseAdapter-多绘制类型-Base相关类 ,然后再重构最新工程过程中,发现还是不太简洁清晰,耦合度有点高,而且之前还搞了一个类专门管理布局配置,还是麻烦。虽然有个工程以及重构完,但是目前重构的新工程,打算采用新的封装。目前小白觉得新的结构还是比较可以。也不会采用三方,剥离出去也没啥依赖,完全可以独立开来使用:
另外新的通用适配器,直接增加了添加监听的接口,一行代码就添加了,蛮方便使用的。同时还提供了想文本,高亮文本,glide加载,圆角加载,也提供了重新调整布局的方法,目前基本都重构完成了。没啥问题。Base页面也做了重新的设计和整理,实际功能页面更加简洁。
直接提供相关类代码(仅供参考,您可能有更好的更适合自己的方案):
/**
* Created by hl on 2018/3/14.
*/
public abstract class BaseMulDataModel {
private int drawType = 0;
public int getDrawType() {
return drawType;
}
public void setDrawType(int drawType) {
this.drawType = drawType;
}
}
BaseMulViewHolder.java - 报错的方法删除即可(根据你自己需要扩展修改完善,关于高亮本工具类之前文章有提到)
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.xxx.app.common.utils.GlideUtil;
import com.xxx.app.common.utils.HighLightKeyWordUtil;
/**
* Created by hl on 2018/3/14.
*/
public class BaseMulViewHolder<T extends BaseMulDataModel> extends RecyclerView.ViewHolder {
private View itemView;
private SparseArray<View> views = new SparseArray<>();
public BaseMulViewHolder(View itemView) {
super(itemView);
this.itemView = itemView;
}
/**
* 获取视图
*
* @return
*/
public View getItemView() {
return itemView;
}
/**
* 获取子控件
*
* @param id
* @param <V>
* @return
*/
public <V extends View> V getView(int id) {
View view = views.get(id);
if (null == view) {
view = itemView.findViewById(id);
views.put(id, view);
}
return (V) view;
}
/**
* 设置文本 - 字符串
*
* @param viewId
* @param content
* @return
*/
public BaseMulViewHolder setText(int viewId, String content) {
((TextView) getView(viewId)).setText(content);
return this;
}
/**
* 设置文本 - 字符串
*
* @param viewId
* @param visibility
* @return
*/
public BaseMulViewHolder setVisible(int viewId, int visibility) {
getView(viewId).setVisibility(visibility);
return this;
}
/**
* 设置文本 - 资源
*
* @param viewId
* @param resId
* @return
*/
public BaseMulViewHolder setText(int viewId, int resId) {
((TextView) getView(viewId)).setText(resId);
return this;
}
/**
* 设置文本颜色
*
* @param viewId
* @param color
* @return
*/
public BaseMulViewHolder setTextColor(int viewId, int color) {
((TextView) getView(viewId)).setTextColor(color);
return this;
}
/**
* 设置文本颜色
*
* @param viewId
* @param colorId
* @return
*/
public BaseMulViewHolder setTextColor(Context context, int viewId, int colorId) {
((TextView) getView(viewId)).setTextColor(context.getResources().getColor(colorId));
return this;
}
/**
* 设置可用性
*
* @param viewId
* @param bEnable
*/
public void setEnable(int viewId, boolean bEnable) {
getView(viewId).setEnabled(bEnable);
}
/**
* 设置控件背景
*
* @param viewId
* @param drawable
* @return
*/
public BaseMulViewHolder setBackground(int viewId, Drawable drawable) {
getView(viewId).setBackground(drawable);
return this;
}
/**
* 设置控件背景
*
* @param viewId
* @param viewId
* @param drawableId
* @return
*/
public BaseMulViewHolder setBackground(Context context, int viewId, int drawableId) {
getView(viewId).setBackground(context.getResources().getDrawable(drawableId));
return this;
}
/**
* 设置高亮文本 - 独家首发
*
* @param viewId
* @param content
* @return
*/
public BaseMulViewHolder setHighLightText(int viewId, String content, String[] highText) {
((TextView) getView(viewId)).setText(HighLightKeyWordUtil.getBackgroudKeyWord(
new int[]{Color.parseColor("#ffffff"), Color.parseColor("#ffffff")},
new int[]{Color.parseColor("#febc48"), Color.parseColor("#f13b2f")},
content, highText));
return this;
}
/**
* 设置高亮文本 - "进行中", "报名中", "已结束"
*
* @param viewId
* @param content
* @return
*/
public BaseMulViewHolder setHighLightTextB(int viewId, String content, String[] highText) {
((TextView) getView(viewId)).setText(HighLightKeyWordUtil.getBackgroudKeyWord(
new int[]{Color.parseColor("#ffffff"), Color.parseColor("#ffffff"), Color.parseColor("#ffffff")},
new int[]{Color.parseColor("#26d191"), Color.parseColor("#febc48"), Color.parseColor("#9f9f9f")},
content, highText));
return this;
}
/**
* 设置高亮文本 - 专题
*
* @param viewId
* @param content
* @return
*/
public BaseMulViewHolder setHighLightTextTopic(int viewId, String content) {
((TextView) getView(viewId)).setText(HighLightKeyWordUtil.getBackgroudKeyWord(
new int[]{Color.parseColor("#ffffff")},
new int[]{Color.parseColor("#477ae4")},
content, new String[]{"猎云专题"}));
return this;
}
/**
* 设置圆角图片ImageView
*
* @param context
* @param viewId
* @param imgUrl
* @return
*/
public BaseMulViewHolder setRoundImageView(Context context, int viewId, int placeResource, String imgUrl) {
Glide.with(context)
.setDefaultRequestOptions(new RequestOptions()
.centerCrop()
.placeholder(placeResource)
.fitCenter() // 解决了有时候加载显示被裁剪等问题
)
.load(imgUrl)
.apply(GlideUtil.getRoundRe(context, 4))
//.placeholder(R.drawable.home_list_img_default)
//.error(R.mipmap.pic_default)
.into((ImageView) getView(viewId));
return this;
}
/**
* 设置图片ImageView
*
* @param context
* @param viewId
* @param imgUrl
* @return
*/
public BaseMulViewHolder setImageView(Context context, int viewId, int placeResource, String imgUrl) {
Glide.with(context)
.setDefaultRequestOptions(new RequestOptions()
.centerCrop()
.placeholder(placeResource)
.fitCenter() // 解决了有时候加载显示被裁剪等问题
)
.load(imgUrl)
//.placeholder(R.drawable.home_list_img_default)
//.error(R.mipmap.pic_default)
.into((ImageView) getView(viewId));
return this;
}
/**
* 设置图片ImageView
*
* @param context
* @param viewId
* @param imageRourceId
* @return
*/
public BaseMulViewHolder setImageView(Context context, int viewId, int placeResource, int imageRourceId) {
Glide.with(context)
.load(imageRourceId)
.placeholder(placeResource)
.into((ImageView) getView(viewId));
return this;
}
}
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import java.lang.ref.WeakReference;
import java.util.List;
/**
*@Author: hl
*@Date: created at 2019/7/17 17:44
*@Description: 基础适配器 - 支持多布局
*/
public abstract class BaseMutilayoutAdapter<T extends BaseMulDataModel> extends RecyclerView.Adapter<BaseMulViewHolder> {
private WeakReference<Context> contextWeakReference = null;
private List<T> datas;
private OnItemClickListener<T> onItemClickListener;
public BaseMutilayoutAdapter(Context context, List<T> datas) {
this.contextWeakReference = new WeakReference<>(context);
this.datas = datas;
}
@NonNull
@Override
public BaseMulViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
BaseMulViewHolder baseMulViewHolder = getHolder(contextWeakReference.get(), viewGroup, viewType);
resizeHolder(contextWeakReference.get(), baseMulViewHolder, viewType);
return baseMulViewHolder;
}
@Override
public void onBindViewHolder(@NonNull BaseMulViewHolder baseMulViewHolder, int postion) {
bindData(contextWeakReference.get(), baseMulViewHolder, datas.get(postion), postion, getItemViewType(postion));
}
@Override
public int getItemCount() {
return null == datas ? 0 : datas.size();
}
@Override
public int getItemViewType(int position) {
return datas.get(position).getDrawType();
}
/**
* 设置监听接口
* @param onItemClickListener
*/
public void setOnItemClickListener(OnItemClickListener<T> onItemClickListener){
this.onItemClickListener = onItemClickListener;
}
/**
* 给控件添加点击事件
* @param v
* @param position
* @param t
* @param itemViewType
*/
public void addOnItemClickListener(View v, int position, T t, int itemViewType, Object externParams){
if (null != v){
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != onItemClickListener){
onItemClickListener.onClick(v, position, t, itemViewType, externParams);
}
}
});
}
}
/**
* 直接回调点击事件
* @param v
* @param position
* @param t
* @param itemViewType
*/
public void dispatchOnItemClickListener(View v, int position, T t, int itemViewType, Object externParams){
if (null != onItemClickListener){
onItemClickListener.onClick(v, position, t, itemViewType, externParams);
}
}
// 子类实现布局加载返回ViewHolder
protected abstract BaseMulViewHolder getHolder(Context context, ViewGroup parent, int viewType);
// 中间处理下布局问题 - 比如设置下图片一定比例的大小
protected abstract void resizeHolder(Context context, BaseMulViewHolder baseHolder, int viewType);
// 子类实现对不同的item进行操作
protected abstract void bindData(Context context, BaseMulViewHolder baseHolder, T t, int postion, int itemViewType);
/**
* 创建一个监听事件的接口
*/
public interface OnItemClickListener<T> {
void onClick(View v, int position, T t, int itemViewType, Object externParams);
}
}
ListView版本照着这个做类似封装就行,主要就是创建视图的时候不太一样:比如:
image来个使用案例:
ActivityListAdapter.java - 里面的布局文件呀,具体填充数据根据自己项目来就行了。
import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
import com.xxx.app.R;
import com.xxx.app.base.adapter.BaseMulDataModel;
import com.xxx.app.base.adapter.BaseMulViewHolder;
import com.liexxxyunwang.app.base.adapter.BaseMutilayoutAdapter;
import com.xxx.app.common.utils.DensityUtil;
import com.xxx.app.common.utils.system.ScreenUtil;
import com.xxx.app.modules.activitys.bean.ActivitysBean;
import java.util.List;
/**
* @Author: hl
* @Date: created at 2019/7/17 18:02
* @Description: 快讯详情适配器
*/
public class ActivityListAdapter<T extends BaseMulDataModel> extends BaseMutilayoutAdapter {
public ActivityListAdapter(Context context, List<T> datas) {
super(context, datas);
}
@Override
protected BaseMulViewHolder getHolder(Context context, ViewGroup parent, int viewType) {
switch (viewType) {
case 1: // 活动
return new BaseMulViewHolder<ActivitysBean>(
LayoutInflater.from(context).inflate(R.layout.fragment_activity_promotion_item, parent,
false));
case 2: // 峰会
return new BaseMulViewHolder<ActivitysBean>(
LayoutInflater.from(context).inflate(R.layout.fragment_activity_fenghui_item, parent,
false));
default:
return null;
}
}
@Override
protected void resizeHolder(Context context, BaseMulViewHolder baseHolder, int viewType) {
switch (viewType) {
case 1: // 活动
ScreenUtil.setConstraintLayoutWH(baseHolder.getView(R.id.fapi_posterIv), (int) (150 * 3), (int) (90 * 3));
break;
case 2: // 峰会
ScreenUtil.setConstraintLayoutWHNoRatio(baseHolder.getView(R.id.fafli_posterIv), ScreenUtil.SCREEN_WIDTH - DensityUtil.dip2px(30), (40 * (ScreenUtil.SCREEN_WIDTH - DensityUtil.dip2px(30))) / 67);
break;
}
}
@Override
protected void bindData(Context context, BaseMulViewHolder baseHolder, BaseMulDataModel baseMulDataModel, int postion, int itemViewType) {
ActivitysBean activitysBean = (ActivitysBean) baseMulDataModel;
switch (itemViewType) {
case 1: // 活动
String resultTitle = activitysBean.getStatus_html();
resultTitle += " " + activitysBean.getTitle();
baseHolder.setHighLightTextB(R.id.fapi_titleTv, resultTitle, new String[]{"进行中", "报名中", "已结束"});
baseHolder.setText(R.id.fapi_timeTv, activitysBean.getStime());
baseHolder.setText(R.id.fapi_postionTv, activitysBean.getAddress());
baseHolder.setImageView(context, R.id.fapi_posterIv, R.drawable.activity_list_default_01, activitysBean.getPoster());
break;
case 2: // 峰会
TextView fllita_joinTv = (TextView) baseHolder.getView(R.id.fafli_joinTv);
if (activitysBean.getStatus().equals("completed")) {
fllita_joinTv.setEnabled(false);
fllita_joinTv.setBackground(context.getResources().getDrawable(R.drawable.corners_rectangle_grayb_selected));
} else if (activitysBean.getStatus().equals("ing")) {
fllita_joinTv.setEnabled(false);
fllita_joinTv.setBackground(context.getResources().getDrawable(R.drawable.corners_rectangle_grayb_selected));
} else if (activitysBean.getStatus().equals("will")) {
fllita_joinTv.setEnabled(true);
fllita_joinTv.setBackground(context.getResources().getDrawable(R.drawable.corners_rectangle_blue_selected));
}
fllita_joinTv.setText(activitysBean.getStatus_html());
baseHolder.setText(R.id.fafli_titleTv, activitysBean.getTitle());
baseHolder.setText(R.id.fafli_timeTv, activitysBean.getStime());
baseHolder.setText(R.id.fafli_postionTv, activitysBean.getCity());
baseHolder.setImageView(context, R.id.fafli_posterIv, R.drawable.activity_list_default_01, activitysBean.getPoster());
addOnItemClickListener(fllita_joinTv, postion, baseMulDataModel, itemViewType, "buy_ticket");
break;
}
addOnItemClickListener(baseHolder.getItemView(), postion, baseMulDataModel, itemViewType, null);
}
}
小白知道网上有很多关于通用适配器的封装以及一些三方库,这个看你自己。小白之前也尝试过阿里的vlayout的使用。只不过自己想尝试学下,就搞搞了!加油,一起努力,同时多看看别人的封装,别人的思想也还蛮不错的呢!
关于我的Base页面,做个记录,目前基本上很多东西都封装到了base页面(baseactivity, basefragment..以及基于这两个扩展的带极验验证,带请求服务,带Webview浏览的扩展base页面),所以其他页面只要继承基础页面或者相关扩展的基础页面,基本上转圈进度条,加载更多展示无更多,显示空数据,设置沉浸状态栏颜色,设置占位布局都没问题了:
小白个人想法和设计,供参考 - 另外权限也是封装到基础页面了,只需要调用方法就可以获得相应处理回调等!
image有想法可以随时交流!要开始锻炼身体了呀。。哎!脆弱的一批.....