Data Binding 打造RecyclerView 万能适配器

来源:互联网 发布:抽风解说 知乎 编辑:程序博客网 时间:2024/06/04 08:18

最近因为项目需要,采用了data bind 来封装了一下RecyclerView的适配器,抽象出了Adapter.

至于不了解data bind是什么可以点击这里。

我们仔细观察RecyclerAdapter可以发现主要是实现onCreateViewHolder(ViewGroup parent, int viewType)和onBindViewHolder(RecyclerView.ViewHolder holder, int position)这两个方法。

所以在我们的父类中我们将这两个方法抽出来。onCreateViewHolders是创建我们的ViewHolder所以这里我们只需拿到布局的引用即可

@Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        ViewDataBinding binding = DataBindingUtil.inflate(                LayoutInflater.from(parent.getContext()),                getItemLayoutId(viewType),                parent,                false);        final RecyclerViewHolder holder = new RecyclerViewHolder(binding.getRoot());        holder.setBinding(binding);        if( null != myItemClickListener){            holder.itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    myItemClickListener.onItemClick(holder.itemView,holder.getLayoutPosition());                }            });        }        if( null != myItemLongClickListener){            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {                @Override                public boolean onLongClick(View v) {                    myItemLongClickListener.onItemLongClick(holder.itemView,holder.getLayoutPosition());                    return true;                }            });        }        return holder;    }

onBindViewHolder()方法则主要是我们具体的操作。

 @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        RecyclerViewHolder recyclerViewHolder = (RecyclerViewHolder) holder;        switch (mMode){            case TYPE_NORMAL:                bindData(recyclerViewHolder,mData.get(position));                break;            case TYPE_CUSTOM:                bindData(recyclerViewHolder,mData.get(position));                bindCustomData(recyclerViewHolder,position,mData.get(position));                break;        }    }

在父类中其实并不用管这些,子类只需继承并实现以下几个方法

/**     * 布局引用     * @param viewType     * @return     */    abstract public int getItemLayoutId(int viewType);    /**     * data bind Variable 引用     * @return     */    abstract public int getVariableId();    /**     * 自定义操作     * @param holder     * @param position     * @param item     */    abstract public void bindCustomData(RecyclerViewHolder holder,int position,T item);    /**     * 加载模式     * @return     */    abstract public int getStartMode();

getItemLayoutId()这个方法子类实现并返回你的布局文件引用。

getVariableId()这个是返回你布局中使用data binding所命名的变量引用。

bindCustomData()在这个方法中,如果你的布局复杂,可以实现自己具体的事件。

getStartMode()这个方法返回的是你所选择加载的模式,如果你需要使用bindCustomData()这个方法,你不能返回0.

在这里我们还实现了统一的ViewHolder

public class RecyclerViewHolder extends RecyclerView.ViewHolder {    private ViewDataBinding binding;    public RecyclerViewHolder(View itemView) {        super(itemView);    }    public ViewDataBinding getBinding() {        return binding;    }    public void setBinding(ViewDataBinding binding) {        this.binding = binding;    }}

RecyclerViewHolder中使用了data binding框架。具体使用可以查看链接。

具体例子:

public class UserAdapter extends RecyclerBaseAdapter<User> {    public UserAdapter(List<User> mData, Context mContext) {        super(mData, mContext);    }    @Override    public int getItemLayoutId(int viewType) {        return R.layout.main_item;    }    @Override    public int getVariableId() {        return BR.users;    }    @Override    public void bindCustomData(RecyclerViewHolder holder, int position, User item) {    }    @Override    public int getStartMode() {        return 0;    }}

可以看到我们继承了RecyclerBaseAdapter实现了一个UserAdapter在这个方法中实现了上面所述的4个方法。

我们的User也很简单:

public class User {    private String name;    private String avatar;    private String age;    public User(){    }    public User(String name, String avatar, String age) {        this.name = name;        this.avatar = avatar;        this.age = age;    }    public String getAvatar() {        return avatar;    }    public void setAvatar(String avatar) {        this.avatar = avatar;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getAge() {        return age;    }    public void setAge(String age) {        this.age = age;    }}

这有头像,名字,年龄
布局文件 main_item.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto">    <data>        <variable            name="users"            type="com.red.allrecyclerdemo.models.User"/>    </data>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginBottom="10dp"            android:orientation="horizontal">            <ImageView                android:layout_width="45dp"                android:layout_height="45dp"                android:scaleType="centerCrop"                app:error="@{@drawable/default_image}"                app:imageUrl="@{users.avatar}"/>            <LinearLayout                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_gravity="center"                android:layout_marginLeft="5dp"                android:orientation="vertical">                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_marginBottom="5dp"                    android:text="@{users.name}" />                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:text="@{users.age}"/>            </LinearLayout>        </LinearLayout>    </LinearLayout></layout>

该布局文件显示我们的头像,姓名,年龄而已,做为一个例子也是够了。
然后查看我们的MainActivity.java

public class MainActivity extends AppCompatActivity {    private UserAdapter mAdapter;    private List<User> mUsers;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);        mUsers = new ArrayList<User>();        setData();        mAdapter = new UserAdapter(mUsers,MainActivity.this);        //设置布局管理器        binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));        binding.recyclerView.setAdapter(mAdapter);    }    private void setData(){        for(int i = 0; i < 10; i++){            User user = new User();            user.setAvatar("http://g.hiphotos.baidu.com/image/h%3D200/sign=4d3fabc3cbfc1e17e2bf8b317a91f67c/6c224f4a20a446230761b9b79c22720e0df3d7bf.jpg");            user.setName("小米" + i);            user.setAge(String.valueOf(i));            mUsers.add(user);        }    }}

效果图:
这里写图片描述

Data Binding大大简化了我们的工作量,值得学习。

项目源码

1 0
原创粉丝点击