Android知识进阶(遥远的重头开始)

Android-RecyclerView通用适配器BaseAda

2019-09-26  本文已影响0人  MonkeyLei

之前也是搞了一版MonkeyLei:Android-RecyclerView通用适配器BaseAdapter-多绘制类型-Base相关类 ,然后再重构最新工程过程中,发现还是不太简洁清晰,耦合度有点高,而且之前还搞了一个类专门管理布局配置,还是麻烦。虽然有个工程以及重构完,但是目前重构的新工程,打算采用新的封装。目前小白觉得新的结构还是比较可以。也不会采用三方,剥离出去也没啥依赖,完全可以独立开来使用:

另外新的通用适配器,直接增加了添加监听的接口,一行代码就添加了,蛮方便使用的。同时还提供了想文本,高亮文本,glide加载,圆角加载,也提供了重新调整布局的方法,目前基本都重构完成了。没啥问题。Base页面也做了重新的设计和整理,实际功能页面更加简洁。

直接提供相关类代码(仅供参考,您可能有更好的更适合自己的方案):

BaseMulDataModel.java

/**
 * 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;
    }
}

BaseMutilayoutAdapter.java

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

有想法可以随时交流!要开始锻炼身体了呀。。哎!脆弱的一批.....

上一篇 下一篇

猜你喜欢

热点阅读