Databinding打造RecyclerView万能适配器
2017-12-07 17:12
459 查看
这是最终效果图,用到了两种布局,Listview和Gridview形式的布局,其中垂直布局中显示了不同类型的item。下面示范如何使用,首先BaseRecyleAdapter如下:
public class BaseRecyleAdapter extends RecyclerView.Adapter<BaseRecyleAdapter.ViewHolder> { public List<?> data;//用?代表所有所有类型 Map<Integer, Integer> hashMap; public BaseRecyleAdapter(List<?> data, Map<Integer, Integer> hashMap) { this.data = data; this.hashMap = hashMap; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater from = LayoutInflater.from(parent.getContext()); ViewDataBinding inflate = DataBindingUtil.inflate(from, viewType, parent, false);//引入布局 return new ViewHolder(inflate); } /** * map可以入参多个,也就是添加多布局,至少需要传一个,map中的key代表布局id,value对应布局中实体类的BR id *默认取第一个,也就是把布局id取出来 * @param position * @return */ @Override public int getItemViewType(int position) { Set<Integer> integers = hashMap.keySet(); return integers.iterator().next(); } @Override public void onBindViewHolder(ViewHolder holder, final int position) { Integer varid = hashMap.get(getItemViewType(position)); holder.dataBinding.setVariable(varid, data.get(position));//varid表示的是布局中数据名称对应的BR if (onRecycleitemOnClic != null)//这里是实现item点击 holder.dataBinding.getRoot().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { onRecycleitemOnClic.onItemClic(view, position);//开放接口 } }); } public OnRecycleitemOnClic getOnRecycleitemOnClic() { return onRecycleitemOnClic; } public void setOnRecycleitemOnClic(OnRecycleitemOnClic onRecycleitemOnClic) { this.onRecycleitemOnClic = onRecycleitemOnClic; } OnRecycleitemOnClic onRecycleitemOnClic; public interface OnRecycleitemOnClic { void onItemClic(View view, int position); } @Override public int getItemCount() { if (data == null) return 0; return data.size(); } public class ViewHolder extends RecyclerView.ViewHolder { ViewDataBinding dataBinding; public ViewHolder(ViewDataBinding itemView) { super(itemView.getRoot()); this.dataBinding = itemView; } } }我们在activity_main中写的布局如下:
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data class="com.rvadapter.recyclerviewadapter.MainData"> </data> <RelativeLayout xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.rvadapter.recyclerviewadapter.activity.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/rv_main" android:layout_width="match_parent" android:layout_height="wrap_content"> </android.support.v7.widget.RecyclerView> <android.support.v7.widget.RecyclerView android:id="@+id/rv_main_grid" android:layout_below="@+id/rv_main" android:layout_width="match_parent" android:layout_height="wrap_content"> </android.support.v7.widget.RecyclerView> </RelativeLayout> </layout>上面data里面的class是我们定义的类名,这个类是databinding自己创建的“隐形”类(不直接显示在文件夹中,但存在),我们这里定义了两个recyclerview,水平和垂直的,这里不用一个Recyclerview是因为嵌套本身也
ca45
会增加代码的耦合性,如果内容非常丰富多样的话以后改起来麻烦。
下面是MainActivity:
public class MainActivity extends FragmentActivity { private MainData mainData; private TestListItemAdapter mainAdapter; public BaseRecyleAdapter mainGridAdapter; private List<UserInfo> userInfo; private LinearLayoutManager linearLayoutManager; private GridLayoutManager gridLayoutManager;//gridview类型的布局 @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); initdatabinding(); } private void initdatabinding() { mainData = DataBindingUtil.setContentView(this, R.layout.activity_main); linearLayoutManager = new LinearLayoutManager(this);//不设置方向默认是垂直 mainData.rvMain.setLayoutManager(linearLayoutManager); userInfo = new ArrayList<>();//初始化的操作放在set之前 setUserInfo(); /** * 这里用TestListItemAdapter是因为adapter里面需要写不同类型的item或者需要自己单独去设置某控件的值 * 如果是相同类型的,比如下面的gridLayoutManager就直接用BaseRecyleAdapter * 这里的BR是dataBinding自动生成的,我们在布局中写好变量,用“BR.变量名”就能得到 */ Map<Integer, Integer> map = new HashMap<>(); map.put(R.layout.item_main, BR.info); map.put(R.layout.item_main_diverse, BR.info2); mainAdapter = new TestListItemAdapter(userInfo, map); mainData.rvMain.setAdapter(mainAdapter); /** * 加载Grid类型的,这里设置3行 */ gridLayoutManager = new GridLayoutManager(this, 3); mainData.rvMainGrid.setLayoutManager(gridLayoutManager); Map<Integer, Integer> gridMap = new HashMap<>(); gridMap.put(R.layout.item_main_grid, BR.gridinfo); mainGridAdapter = new BaseRecyleAdapter(userInfo, gridMap); mainData.rvMainGrid.setAdapter(mainGridAdapter); } private void setUserInfo() { for (int i = 0; i < 5; i++) { UserInfo userInfo = new UserInfo(); userInfo.setTitle("以梦为马,诗酒趁年华" + i); userInfo.setName(" "); userInfo.setCover("http://jyts-public-oss.longruncloud.com/images/4ee98d67ccf5e5d33db6eba5046e1e289eb8d787f7888aab69280e169b4556c5.jpg"); userInfo.setAge("年龄:" + String.valueOf(i)); this.userInfo.add(userInfo); } } }
注释已经很详细,就不赘述了,其中用到了实体类是自己写的,如果是服务端给的接口也是一样用的。Bean代码贴出来:
public class UserInfo { private String cover; private String title; private String name; private String age; public String getCover() { return cover; } public void setCover(String cover) { this.cover = cover; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } 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; } }因为我们垂直布局中需要自己写前面的序号,还有需要自己设置不同类型的item,所以我们需要写自己的Adapter集成BaseRecyleAdapter,重写里面的方法进行设置,就是MainActivity中用到的TestListItemAdapter。
public class TestListItemAdapter extends BaseRecyleAdapter { public TestListItemAdapter(List<?> data, Map<Integer, Integer> hashMap) { super(data, hashMap); } /** * 如果有值不是从bean类里面获取的,需要自己去设置的话就重写此方法 * @param holder * @param position */ @Override public void onBindViewHolder(ViewHolder holder, int position) { super.onBindViewHolder(holder, position); int i = position + 1; String text = i >= 10 ? String.valueOf(i) : String.valueOf("0" + i); holder.dataBinding.setVariable(BR.itemNum, text);//这里就是设置前面的序号 } /** * 编写规则,返回相应布局,比如这里是第四个item加载其他布局 * * @param position * @return */ @Override public int getItemViewType(int position) { if (position == 3) return R.layout.item_main_diverse; else return R.layout.item_main; } }其中需要注意的是在布局中设置图片的话和文字有些不同,我们需要自己实现:
public class ImagBindingUtils { @BindingAdapter("imgurl") public static void bindingImage(ImageView imageView, String url) { Glide.with(imageView.getContext()).load(url).into(imageView);//用的glide加载,在build.gradle中添加依赖就能使用 } }用到的layout我只贴一种,因为其他的都是一样的,我这里只是做了item颜色修改:
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="info2" type="com.rvadapter.recyclerviewadapter.bean.UserInfo" /> <variable name="itemNum2" type="java.lang.String" /> </data> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="10dp"> <TextView android:id="@+id/tv_main_number" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginRight="10sp" android:text="@{itemNum2}" android:textColor="#fb9223" android:textSize="14sp" /> <ImageView android:id="@+id/iv_main_img" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginRight="10dp" android:layout_toRightOf="@+id/tv_main_number" app:imgurl="@{info2.cover}" /> <TextView android:id="@+id/tv_main_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/iv_main_img" android:layout_toRightOf="@+id/iv_main_img" android:text="@{info2.title}" android:textColor="@color/red" android:textSize="10sp" /> <TextView android:id="@+id/tv_main_description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/iv_main_img" android:layout_toRightOf="@+id/iv_main_img" android:text="@{info2.name+info2.age}" android:textColor="@color/gray" android:textSize="10sp" /> <View android:layout_width="match_parent" android:layout_height="0.2dp" android:layout_below="@+id/tv_main_description" android:layout_marginTop="10dp" android:background="@color/gray" /> </RelativeLayout> </layout>UserInfo是我们自己创建的Bean类,我们把全类名引入进来,创建了info2的变量,在textview中通过@{info2.}来使用,具体就是这样,如果需要设置item点击事件的话,在自己建的Apater类里实现BaseRecyleAdapter.OnRecycleitemOnClic,然后再构造器里面添加setOnRecycleitemOnClic(this),最后在实现的onItemClic方法中写我们需要进行的操作即可,具体的使用如下:
public class ListenerBookRankAdapter extends BaseRecyleAdapter implements BaseRecyleAdapter.OnRecycleitemOnClic { private List<RankingBean.SalesBean.BooksBeanDes> booksBeanDes; public ListenerBookRankAdapter(List<?> data, Map<Integer, Integer> hashMap) { super(data, hashMap); this.booksBeanDes = (List<RankingBean.SalesBean.BooksBeanDes>) data; setOnRecycleitemOnClic(this);//2.设置item点击,Base中已写好 } @Override public void onBindViewHolder(final ViewHolder holder, final int position) { super.onBindViewHolder(holder, position); int i = position + 1; String text = i >= 10 ? String.valueOf(i) : String.valueOf("0" + i); holder.dataBinding.setVariable(BR.itemtestnum, text); } @Override public void onItemClic(View view, int position) {//3.重写方法 int id = booksBeanDes.get(position).getBook().getId(); Intent intent = new Intent(); intent.putExtra("ID", id); intent.setClass(view.getContext(), BookRankDetailsActivity.class); view.getContext().startActivity(intent); } }使用过程就是这些,如有问题可以留言,希望可以互相学习,Demo链接是http://download.csdn.net/download/xkyh941/10149648,发现Adapter文件夹里面手抖多建了个新建文件夹,我就不重新上传了,联系管理员麻烦,不会影响使用。
相关文章推荐
- 一步步打造Android RecyclerView万能适配器
- 偷懒新姿势,打造属于RecyclerView的万能适配器Adapter和ViewHolder
- 为RecyclerView打造万能适配器,点击事件,5.0水波纹点击效果
- Data Binding 打造RecyclerView 万能适配器
- 【工具类】打造万能的Listview、GridView和ViewPager和RecyclerView的适配器
- 偷懒新姿势,打造属于RecyclerView的万能适配器Adapter和ViewHolder
- android 用mvp模式来架构自己的app+打造Recyclerview万能适配器
- 打造RecyclerView的万能适配器
- 为RecyclerView打造简单易用扩展性高的万能适配器
- Android 打造自己的解耦JavaBean的RecyclerView万能适配器(三)
- 为RecyclerView打造万能适配器
- Android打造万能适配器--RecyclerView
- 打造android偷懒神器———RecyclerView的万能适配器
- (再次更新)打造RecyclerView万能适配器,上拉刷新,下拉加载
- 偷懒新姿势,打造属于RecyclerView的万能适配器Adapter和ViewHolder
- RecyclerView万能适配器以及点击事件
- 属于RecyclerView的万能适配器Adapter和ViewHolder
- DataBinding的万能ViewPager适配器
- recyclerview万能适配器用法以及源码分析
- Android(无需javabean,支持多item type)的RecyclerView万能适配器,解耦从这里做起