关闭

当 ListView 被 RecyclerView替代,我们拿什么来替代 BaseAdapterHelper 呢?

742人阅读 评论(0) 收藏 举报
分类:

What:什么是 BaseAdapter

大家还记得当前大明上湖畔的的 BaseAdapterHelper 么?哈,开个玩笑哈,应该是 GitHub的 BaseAdapterHelper哈。
关于 BaseAdapterHelper 介绍以及详细用法,我就不在这篇博文里就介绍了。
附上 BaseAdapterHelper 的连接:base-adapter-helper
大家都知道,BaseAdapterHelper是用在 ListView 以及 GrildView 中一个很强大的第三方库。用了这个库之后,相信大家都在开发中节省了相当多的时间。

Why:为什么要改造 BaseAdapterHelper

相信大家现在都在慢慢在项目中开始使用 RecyclerView 了吧。RecyclerView 与 ListView 和 GridView相当的类似,都是能在有限的屏幕空间里展示大量的数据集。但是 RecyclerView 又以高度解耦的特征深受开发者喜爱。虽然RecyclerView 与 ListView 等列表控年有一定的类似(都要 Adapter),但是安卓给我们提供的Adapter 的基类又是不一样的。(关于 RecyclerView 的基本使用,我这里就不做介绍了,大家可以在 csdn上找一找。),那么,我们之前的 BaseAdapterHelper 是不是就不能用了。
所以,我们开始打造RecyclerView 的 BaseAdapterHolder.

How:怎么去改

其实,思路还是跟 BaseAdapter 比较类似的。
一:先创建一个 RecyclerView 的简单工程:
首先,我们看一下布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rlv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

然后是我们MainActivity.java

package wu.yul.baseadater4recyclerview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

import wu.yul.baseadater4recyclerview.adapter.CommonAdapter;

public class MainActivity extends AppCompatActivity {
    private RecyclerView rlv;
    private RecyclerView.LayoutManager mLayoutManager;
    private CommonAdapter mCommonAdapter;
    private List <String> mList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initialize();
    }

    protected void onResume() {
        super.onResume();
    }

    private void initialize() {

        rlv = (RecyclerView) findViewById(R.id.rlv);
        mLayoutManager = new LinearLayoutManager(getApplicationContext());
        mList = new ArrayList<>();
        for(int i=0;i<10;i++){
            mList.add("TestData"+i);
        }
        mCommonAdapter = new CommonAdapter(mList);
        rlv.setLayoutManager(mLayoutManager);
        rlv.setAdapter(mCommonAdapter);
    }
}

然后我们来观察一下 CommonAdapter:

 */
public class CommonAdapter extends RecyclerView.Adapter<CommonAdapter.BaseViewHolder> {
    public List<String> mDataSet;
    public CommonAdapter(List<String> list){
        mDataSet =list;
    }
    public CommonAdapter.BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rlv, parent, false);
        return new BaseViewHolder(view);
    }

    public void onBindViewHolder(CommonAdapter.BaseViewHolder holder, int position) {
        holder.tv.setText(mDataSet.get(position));
    }

    public int getItemCount() {
        return mDataSet.size();
    }

    class BaseViewHolder extends RecyclerView.ViewHolder {
        private TextView tv;
        public BaseViewHolder(View itemView) {
            super(itemView);
            tv = (TextView) itemView.findViewById(R.id.tv);
        }
    }
}

二:改造第一步:提取布局
首先,我们可以看到,在 onCreateViewHolder 里面,变化的就布局以及返回的 Holder 了。但是我们要做是万能的 ViewHolder,所以,其实返回值也是不变的。那我们就把 布局提取出来。改造一下构造函数。

    public CommonAdapter(List<String> list,int resID){
        mDataSet =list;
        this.resID =resID;
    }

以及 OnCreateViewHolder:

   public CommonAdapter.BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(resID, parent, false);
        return new BaseViewHolder(view);
    }

三:onBindViewHolder:
相信大家都知道,在 onBindViewHolder 中,我们把数据与相应的控件进行绑定。而在之前的 BaseAdapterHelper 中,正是把这一个绑定的操作,放在具体的实现类中。那么,我们的思路就比较清晰了。同样,写一个虚函数,并且在 onBindViewHolder中调用。

  public void onBindViewHolder(CommonAdapter.BaseViewHolder holder, int position) {
        convert(holder, mDataSet.get(position));

    }

    public abstract void convert(BaseViewHolder holder, String string);

接下来我们再把内部类 BaseViewHolder 给提取出来,让他集成 RecyclerView.ViewHolder。

public class BaseViewHolder extends RecyclerView.ViewHolder {
    private Context mContext;
    private int position;
    private final SparseArray<View> views;
    private View rootView;
    public BaseViewHolder(View itemView) {
        super(itemView);
        rootView = itemView;
        mContext = itemView.getContext();
        position = getLayoutPosition();
        views = new SparseArray<>();
    }
}

其中,mContext 是用于后期用于加载图片时要用的。views 用于存储后续存放我们从视图中取得的控件。我们写一个 getView 的方法。用于取得对应的控件、

  public View  getView(int resID){
        View view = views.get(resID);
        if(null==view){
            view = rootView.findViewById(resID);
            views.put(resID,view);
        }
        return view;
    }

不过这里,再进行一下改造。因为我们取得的是一个 View,而不是具体的 View 的子类。那么做一个简单的变更就好了。

   public <T extends View> T  getView(int resID){
        View view = views.get(resID);
        if(null==view){
            view = rootView.findViewById(resID);
            views.put(resID,view);
        }
        return (T)view;
    }

然后我们写一个 setText 的方法:

    public BaseViewHolder  setText(int viewID,int resID){
        TextView view = getView(resID);
        view.setText(resID);
        return this;
    }

附一个 BaseViewHolder 的完整代码:

public class BaseViewHolder extends RecyclerView.ViewHolder {
    private Context mContext;
    private int position;
    private final SparseArray<View> views;
    private View rootView;

    public BaseViewHolder(View itemView) {
        super(itemView);
        mContext = itemView.getContext();
        position = getLayoutPosition();
        views = new SparseArray<>();
        rootView = itemView;
    }

    public <T extends View> T getView(int viewID) {
        View view = views.get(viewID);
        if (null == view) {
            view = rootView.findViewById(viewID);
            views.put(viewID, view);
        }
        return (T) view;
    }

    public BaseViewHolder setText(int viewID, int resID) {
        TextView view = getView(resID);
        view.setText(resID);
        return this;
    }
    public BaseViewHolder setText(int viewID, String text) {
        TextView view = getView(viewID);
        view.setText(text);
        return this;
    }
}

那我们回到 MainActivity 中,看看怎么调用:

       mCommonAdapter = new CommonAdapter(mList,R.layout.item_rlv) {
            public void convert(BaseViewHolder holder, String string) {
                holder.setText(R.id.tv,string);
            }
        };

是不是跟我们的之前的BaseAdapterHelper 基本一样啦。最后我们改造 CommonAdapter:

public abstract class CommonAdapter<T> extends RecyclerView.Adapter<BaseViewHolder> {
    public List<T> mDataSet;
    public final int resID;

    public CommonAdapter(List<T> list, int resID) {
        mDataSet = list;
        this.resID = resID;
    }

    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(resID, parent, false);
        return new BaseViewHolder(view);
    }

    public void onBindViewHolder(BaseViewHolder holder, int position) {
        convert(holder, mDataSet.get(position));

    }

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

    public int getItemCount() {
        return mDataSet.size();
    }

}

这样,我们就可以传任意类型的 List 了。当然,BaseViewHolder里还可以加更多复杂的操作,我就不详细介绍了。大家可以参考 文首的 BaseAdapterHelper.
源码:BaseViewHolder

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:4954次
    • 积分:119
    • 等级:
    • 排名:千里之外
    • 原创:7篇
    • 转载:0篇
    • 译文:0篇
    • 评论:4条