近期本人一直在用Databinding,属实好用,最近又发现有小伙伴封装了recyclerView的Adapter,真是太给力了!拿过来与大家分享下。框架中提供了两种适配器类型,single单一数据源和multi混合型数据源,针对不同的需求。一般情况下,我们常用的是single类型,因为列表只定义一种类型数据源,但也不排除列表复杂,引入多种布局,这时候我们可以用MultiTypeAdapter,具体使用后面介绍,我们先来看下封装的Base adapter源码:
public abstract class BaseViewAdapter<T> extends RecyclerView.Adapter框架中定义了两个接口,presenter响应事件,decorator装饰器用来操作混合型适配器中的view及data。{ protected final LayoutInflater mLayoutInflater; protected List<T> mCollection; protected Presenter mPresenter; protected Decorator mDecorator; public interface Presenter { } public interface Decorator { void decorator(BindingViewHolder holder, int position, int viewType); } public BaseViewAdapter(Context context) { mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public void onBindViewHolder(BindingViewHolder holder, int position) { final Object item = mCollection.get(position); holder.getBinding().setVariable(BR.item, item); holder.getBinding().setVariable(BR.presenter, getPresenter()); holder.getBinding().executePendingBindings(); if (mDecorator != null) { mDecorator.decorator(holder, position, getItemViewType(position)); } } @Override public int getItemCount() { return mCollection.size(); } public void remove(int position) { mCollection.remove(position); notifyItemRemoved(position); } public void clear() { mCollection.clear(); notifyDataSetChanged(); } public void setDecorator(Decorator decorator) { mDecorator = decorator; } public void setPresenter(Presenter presenter) { mPresenter = presenter; } protected Presenter getPresenter() { return mPresenter; } }
base类继承自RecyclerView.Adapter重写了bindViewHolder方法,动态设置databingView 中的variable,注意的是框架中声明了item,presenter两个属性,也就是说我们在使用时,recyclerView中的子布局中数据源与响应事件必须为item、presenter,如下:
name="item" type="com.wms.databinding.Student" /> name="presenter" type="com.wms.databinding.RecyclerViewActivity.Presenter" />
dependencies {
compile 'com.github.markzhai:databinding-rv-adapter:1.0.1'
}
android:id="@+id/rv_single"
android:layout_width="match_parent"
android:layout_height="match_parent" />
item_xml:
xmlns:android="http://schemas.android.com/apk/res/android">
name="item"
type="com.wms.databinding.Student" />
name="presenter"
type="com.wms.databinding.RecyclerViewActivity.Presenter" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:drawable/list_selector_background"
android:onClick="@{()->presenter.onItemClick(item)}"
android:padding="10dp">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{"name:\t"+item.name}' />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text='@{"age:\t"+item.age}' />
然后Activity中去添加适配器:
singleTypeAdapter = new SingleTypeAdapter(this, R.layout.item_rv); //设置适配器监听 singleTypeAdapter.setPresenter(new Presenter()); //设置数据源 clear and add singleTypeAdapter.set(getData()); binding.rvSingle.setLayoutManager(new LinearLayoutManager(this)); binding.rvSingle.setAdapter(singleTypeAdapter);
public class Presenter implements BaseViewAdapter.Presenter { public void onItemClick(Student item) { Toast.makeText(RecyclerViewActivity.this, item.getName() + "---" + item.getAge(), Toast.LENGTH_SHORT).show(); } }
public void set(List<T> viewModels) { mCollection.clear(); addAll(viewModels); }addAll在list中add数据:
public void addAll(List<T> viewModels) { mCollection.addAll(viewModels); notifyDataSetChanged(); }
xmlns:android="http://schemas.android.com/apk/res/android">
name="presenter"
type="com.wms.databinding.RecyclerViewActivity.Presenter" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:padding="10dp"
android:textColor="@android:color/holo_red_dark" />
multiTypeAdapter = new MultiTypeAdapter(this); //设置混合布局样式 multiTypeAdapter.addViewTypeToLayoutMap(TITLE_TYPE, R.layout.item_multi_title); multiTypeAdapter.addViewTypeToLayoutMap(ITEM_TYPE, R.layout.item_rv); //设置适配器监听 multiTypeAdapter.setPresenter(new Presenter()); //设置装饰器 multiTypeAdapter.setDecorator(new TitleDecorator()); //设置混合数据源 multiTypeAdapter.add(null, TITLE_TYPE); multiTypeAdapter.addAll(getData(), ITEM_TYPE); binding.rvMulti.setLayoutManager(new LinearLayoutManager(this)); binding.rvMulti.setAdapter(multiTypeAdapter);addViewTypeLayoutMap(int type, int res) 添加布局类型及布局资源,add(object data,int type) 向指定布局中添加数据。其中添加了decorator用来操作混合布局中的指定布局,我demo中是对title布局进行操作:
public class TitleDecorator implements BaseViewAdapter.Decorator { @Override public void decorator(BindingViewHolder holder, int position, int viewType) { if (TITLE_TYPE == viewType) { ItemMultiTitleBinding titleBinding = (ItemMultiTitleBinding) holder.getBinding(); titleBinding.title.setText("This is multi title"); } } }运行如下: