26
2017
09

Android开发之定义万能适配器

前言
在日常的工作中不免会遇见一些展示列表的需求,比如一些新闻或者电商的项目就会有这样类似的需求,这个时候我们可以用一些列表控件来完成这样的功能。作为Android的源头Google也给我们提供相对应的列表控件供我们开发者使用,比如ListView,GridView,RecyclerView这三大列表控件,现在市面上常用的就是RecyclerView。RecyclerView是Google在Android5.0系统推出的时候一起推出的控件之一,对于列表控件的使用,适配器无疑是使用过程中最需要注意的点,但是有的时候可能在一个项目中我们需要用到很多次这个列表,这时就可以定义一个父类的适配器来供我们使用,可以节省很多冗余的代码和时间。接下来就来介绍一下这个适配器的编写。
步骤一:
我们都知道RecyclerView的适配需要用一个ViewHolder内部类来去对相对应展示的控件进行转换,那么我们可以先把这个内部类给定义出来,定义一个BaseViewHolder继承与RecyclerView.ViewHolder代码如下;
import android.app.Activity;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import jiubeirobot.com.robotshop.utils.glide.GlideImageLoadImpl;

/**
* ==========================
* 创建人:TheJoker丶豪 on
* 创建时间:2017/8/21.
* 创建内容:ViewHolder的基类
* ==========================
*/

public class BaseViewHolder extends RecyclerView.ViewHolder {
private SparseArray sparseArray;
private View converView;
private int postion;
private Context context;

public void setPostion(int postion) {
    this.postion = postion;
}

public int getPostion() {
    return postion;
}

public BaseViewHolder(View itemView, Context context) {
    super(itemView);
    this.context = context;
    this.sparseArray = new SparseArray<>();
    this.converView = itemView;
}

public static BaseViewHolder get(Context context, ViewGroup viewGroup, int layoutID) {
    View view = LayoutInflater.from(context).inflate(layoutID, viewGroup, false);
    return new BaseViewHolder(view, context);
}

public <T extends View> T getView(int viewId) {
    View view = sparseArray.get(viewId);
    if (view == null) {
        view = converView.findViewById(viewId);
        sparseArray.put(viewId, view);
    }
    return (T) view;
}

public void setText(int viewId, String txt) {
    TextView tv = getView(viewId);
    tv.setText(txt);
}

public void setImg(int viewId, String url) {
    ImageView img = getView(viewId);
    GlideImageLoadImpl.getInstance().load((Activity) context, url, img);
}

}
步骤二:
创建一个抽象父类BaseRecyclerAdapter来供子类继承并且使用泛型T来映射实体类对象,该类需要继承与RecyclerView.Adapter里面的泛型使用刚刚创建的内部类,然后使用集合来对实体类对象数据做一个映射,代码如下:

protected Context context;
protected List<T> list;
private int layoutId;

public BaseRecyclerAdapter(Context context, List<T> list, int layoutId) {
    this.context = context;
    this.list = list;
    this.layoutId = layoutId;
}

@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    BaseViewHolder baseViewHolder = BaseViewHolder.get(context, parent, layoutId);
    return baseViewHolder;
}

@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
    holder.setPostion(position);
    convert(holder, list.get(position));
}

public abstract void convert(BaseViewHolder holder, T t);

@Override
public int getItemCount() {
    if (list == null) {
        return 0;
    }
    return list.size();
}

好到这里一个父类的适配器就编写完成,具体使用步骤如下:
创建一个类继承与 BaseRecyclerAdapter,将我们需要映射的实体类对象传入泛型T,然后实现父类的构造方法和重写convert方法传入布局ID和实体类对象所映射的集合就好,代码如下:

public DemoAdapter(Context context, List<T> list) {
    super(context, list, R.layout.item_shop_list);
}

@Override
public void convert(BaseViewHolder holder, final T bean) {

}
到这里一个父类的适配器就全部完成,注意:该适配只适用于单一数据类型的列表,如果是多类型的数据,请按照此思路另写一份,谢谢

上一篇:2017年腾讯移动客户端面试总结-失败经验 下一篇:基于ViewDragHelper实现侧滑