模仿于 b 站番剧列表显示方式,而不止于其显示方式
来源:互联网 发布:linux vi 替换命令 编辑:程序博客网 时间:2024/04/30 02:50
MultiRecyclerAdapter
- MultiRecyclerAdapter
MultiRecyclerAdapter for RecyclerView
- HeaderFooterAdapter
Add Footer and Header for your adapter!
下面先介绍第一个MultiRecyclerAdapter
模仿 b 站列表的 Adapter,适用于 RecyclerView.
先看一下原样式效果:
像这样:
还有这样:
用法
继承项目 library 中的抽象类MultiBaseRecyclerAdapter<K, V>
.就像下面这样:
/** * Created by : youngkaaa on 2016/10/9. * Contact me : 645326280@qq.com */public class MyMultiAdapter extends MultiBaseRecyclerAdapter<TitleBean,ContentBean> { private OnItemClickedListener mItemClickedListener; private Context mContext; public MyMultiAdapter(Context context, Map<TitleBean, List<ContentBean>> data) { super(context, data); mContext=context; } public MyMultiAdapter(Context context, List<TitleBean> keys, Map<TitleBean, List<ContentBean>> data) { super(context, keys, data); mContext=context; } public void setItemClickedListener(OnItemClickedListener itemClickedListener) { mItemClickedListener = itemClickedListener; } @Override public int getTitleLayoutId() { return R.layout.title_layout; } @Override public int getContentLayoutId() { return R.layout.recycler_item; } @Override public void bindData(int type, BaseViewHolder holder, Object data) { TextView textViewLeft=holder.getViewById(R.id.textViewTitleLeft); TextView textViewRight=holder.getViewById(R.id.textViewTitleRight); TextView textViewContent=holder.getViewById(R.id.textViewRecyclerItemContent); ImageView imageView=holder.getViewById(R.id.imageViewContentIco); if(type==TYPE_TITLE){ final TitleBean bean= (TitleBean) data; textViewLeft.setText(bean.getLeftTitle()); textViewRight.setText(bean.getRightTitle()); textViewLeft.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(mItemClickedListener!=null){ mItemClickedListener.onClick(TYPE_TITLE,bean,view); } } }); textViewRight.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(mItemClickedListener!=null){ mItemClickedListener.onClick(TYPE_TITLE,bean,view); } } }); }else{ final ContentBean bean= (ContentBean) data; textViewContent.setText(bean.getContent()); Glide.with(mContext).load(bean.getPicUrl()) .centerCrop().into(imageView); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(mItemClickedListener!=null){ mItemClickedListener.onClick(TYPE_TITLE,bean,view); } } }); } }}
这里我传入的K
、V
分别为:TitleBean
和ContentBean
。这两个分别是自定义的类。 注意:前者K
是用于 Adapter 中的每个Title
布局中的,即将用于Title
布局的赋值,下面是我的TitleBean
的代码:
/** * Created by : youngkaaa on 2016/10/9. * Contact me : 645326280@qq.com */public class TitleBean { private String leftTitle; private String rightTitle; public TitleBean() { } public TitleBean(String left, String right) { this.leftTitle = left; this.rightTitle = right; } public void setLeftTitle(String leftTitle) { this.leftTitle = leftTitle; } public String getLeftTitle() { return leftTitle; } public void setRightTitle(String rightTitle) { this.rightTitle = rightTitle; } public String getRightTitle() { return rightTitle; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; TitleBean person = (TitleBean) obj; if (leftTitle != null && person.leftTitle != null && rightTitle != null && person.rightTitle != null && leftTitle.equals(person.leftTitle) && person.rightTitle.equals(rightTitle)) { return true; } return true; } @Override public int hashCode() { return 7 * leftTitle.hashCode() + 13 * rightTitle.hashCode(); }
注意,要重写equals()
和hashCode()
方法哦,因为我们这里用到了Map<>
,而我们知道:当Map<>
的键是一个自定义类(在我的这个 demo 中是 TitleBean)时,是需要重写上面这两个方法的,因为Map<>
中是通过上面那两个方法来确定键是不是一样的。所以你需要重写他们俩。而至于如何重写就不是这里的重点了,去找 java 有关书籍看看吧。
然后就是ContentBean
类,这个类是用来给非title
布局的布局来赋值的。这个类不需要重写上面那两个方法,因为一个是值,一个是键,只有键是自定义类时才需要重写那两个方法!
然后继承实现MultiBaseRecyclerAdapter
中的方法,下面逐个解释:
- MultiBaseRecyclerAdapter(Context context, Map<titlebean, list> data)
构造方法之一,第一个参数不用讲了吧,第二个参数就是一个Map<>
参数,其中该Map<>
的键用来给Title
布局赋值,然后每个键对应的值用来给指定的非Title
布局赋值。这样的话可以简便的实现最终的效果,但是由于Map<>
的一个特点:遍历取出来的值每次顺序都是不一样的,即不能指定顺序,所以我还提供了另外一个重载构造方法,你可以按需继承,即当你不关心最终的列表顺序,只需要显示出来内容就行,那么你就继承实现该构造方法,如果你需要指定顺序,那么你就继承下一个构造方法吧!
- MultiBaseRecyclerAdapter(Context context, List keys, Map<titlebean, list> data)
构造方法之二,第一个参数不讲了。第二个参数就是你单独传入的键,用来给Title
布局赋值,然后后面的Map<>
中的对应值来给指定的非Title
布局赋值。与上面的构造方法唯一不同的就是本构造方法可以指定列表顺序,即按你传入的第二个参数的顺序来放置布局。两种常用的供不同需求使用!
- getTitleLayoutId()
重写本方法来返回Title
布局的布局资源 id。所以说你可以给Title
部分添加任何你想要的样式,而不只是上面 b 站的样式!
- getContentLayoutId()
重写本方法来返回非Title
布局的布局资源 id。所以说你可以给非Title
部分添加任何你想要的样式,而不只是上面 b 站的样式!
- bindData(int type, BaseViewHolder holder, Object data)
该方法就可以让你来绑定布局数据。第一个参数type
有两个可选的:TYPE_TITLE
和TYPE_OTHER
。你可以通过判断来决定具体现在是要给那个布局绑定数据,第二个参数holder
就是指定的BaseViewHolder
,你可以用它来获得指定view
,通过其getViewById()
方法。第三个参数是该布局应该绑定的数据,当type
为TYPE_TITLE
时,该data
其实就是一个TitleBean
类型的数据,即你上面重写时设置的K
的类型,你可以放心的使用类型转换,当type
为TYPE_OTHER
时,该data
其实就是一个ContentBean
类型的数据,即你上面重写时设置的V
的类型,你可以放心的使用类型转换来绑定。这里没有牵扯到position
,这些我在MultiBaseRecyclerAdapter
中都做好了,哪个位置应该绑定Map<>
中的哪个位置的数据我已经处理好直接返回给你了,你就光绑定就行了!示例代码如下:
@Override public void bindData(int type, BaseViewHolder holder, Object data) { TextView textViewLeft=holder.getViewById(R.id.textViewTitleLeft); TextView textViewRight=holder.getViewById(R.id.textViewTitleRight); TextView textViewContent=holder.getViewById(R.id.textViewRecyclerItemContent); ImageView imageView=holder.getViewById(R.id.imageViewContentIco); if(type==TYPE_TITLE){ final TitleBean bean= (TitleBean) data; textViewLeft.setText(bean.getLeftTitle()); textViewRight.setText(bean.getRightTitle()); textViewLeft.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(mItemClickedListener!=null){ mItemClickedListener.onClick(TYPE_TITLE,bean,view); } } }); textViewRight.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(mItemClickedListener!=null){ mItemClickedListener.onClick(TYPE_TITLE,bean,view); } } }); }else{ final ContentBean bean= (ContentBean) data; textViewContent.setText(bean.getContent()); Glide.with(mContext).load(bean.getPicUrl()) .centerCrop().into(imageView); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(mItemClickedListener!=null){ mItemClickedListener.onClick(TYPE_TITLE,bean,view); } } }); } }
注意:
如果你使用第二个构造方法,那么要注意传入的键的数量和
Map<>
中对应的值的数量要相同,否则会抛出一个RuntimeException
,内容为:Key's size should be equal to the Map's key size!你如果要设置点击事件的话,你可以仿照我在项目中的实现,我内部现成的提供了一个点击事件的接口,你可以按照我的样子来设置点击事件,这样很轻松。当然你也可以自己定义使用自己定义的接口。
上面使用的是
GridLayoutManager
,当然你也可以使用LinearLayout
,其中LinearLayout
布局比较简单,这里就不再解释了。需要注意的是GridLayoutManager
,在使用GridLayoutManager
时,你需要做下面这一步:
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return mMutiAdapter.isTitleView(position)?gridLayoutManager.getSpanCount():1; }});
即给RecyclerView
中每个Item
设置 span,显然Title
布局要占据一整行的,而非Title
就按应有的一个占用一个格子,所以上面的mMutiAdapter.isTitleView(position)?gridLayoutManager.getSpanCount():1
就不难懂了吧。而至于上面用到的isTitleView()
方法你光使用就行了,我帮你做好了判断的,不要乱继承实现该方法哦!
写的差不多了,够详细了,没写到位的请查看我提供的 demo 吧,里面的代码都比较简单,所以注释就没写多少,个别重要的地方有注释。
下面贴一下运行图:
更多样式请自行实现!
下面介绍第二个HeaderFooterAdapter
下面先贴出图:
然后,用法很简单,就像下面这样(只贴出部分有关代码):
mMutiAdapter = new MyMultiAdapter(this, initListKeys(), initMapData());headerFooterAdapter=new HeaderFooterAdapter(this,mMutiAdapter);headerFooterAdapter.setFooterResId(R.layout.footer_layout);headerFooterAdapter.setHeaderResId(R.layout.header_layout);mRecyclerView.setAdapter(headerFooterAdapter);
就是先调用构造方法(上面第二句),将你已经实现了的 Adapter
传入,这样做的优点就是几乎不用修改你原来的逻辑,只需要给你原先的RecyclerAdapter
外面再包裹一个Adapter
就行了,然后设置该Adapter
给你的RecyclerView
,这样原来的逻辑都在,就多了上面两三行代码就让你的RecyclerView
有了Header
和Footer
。更多用法请查看项目内的 Demo.
你需要注意的是在绑定Adapter
和RecyclerView
时,一定要记得在之前调用setFooterResId()
和setHeaderResId()
方法将你的布局传入哦!!
欢迎大神提意见,你有任何好的 pr 都欢迎!
如果该项目对你有用的话,给个star
以示鼓励吧!你也可以顺便围观一下我的其他项目谢谢!
- 模仿于 b 站番剧列表显示方式,而不止于其显示方式
- 继承于CCObject而非CCLayer的界面的显示
- Visual C# 2005 - 如何于DataGridView控件中以跨数据行方式显示数据
- 如何于DataGridView控件中以跨数据行方式显示数据
- 如何于DataGridView控件中以跨数据行方式显示数据
- 如何于DataGridView控件中以跨数据行方式显示数据
- Visual C# 2005 - 如何于DataGridView控件中以跨数据行方式显示数据
- 设置列表的显示方式
- 列表项的显示方式
- 融于心而表于行 之 磁盘的管理方式
- 关于《不止于Java》
- 代码不止于工作
- 不止于技术
- 按钮随意隐藏于显示
- Fragment的隐藏于显示
- WEB方式使用DOTMSN显示好友列表
- Struts2+Hibernate3将图片保存于mysql数据库并将其显示在JSP页面
- 定义一个结构体用于保存员工信息,写入文件后并将其显示出来
- 学习
- 琐碎知识点记录
- Practice Round APAC test 2017——Problem D. Sums of Sums
- 什么是wall clock time
- 安装zlib pcre nginx时报错
- 模仿于 b 站番剧列表显示方式,而不止于其显示方式
- 在红尘的最深处重逢
- 面向对象的三个特性
- 100天土鸡饲养计划(65)
- linux下python脚本文件的执行与编码解析
- 【LeetCode】Sum of Left Leaves 左叶子之和
- ubuntu 14.04安装mxnet / CPU实用教程
- C Primer Plus学习 四十 本章中您将学习下列内容
- 索引(从零开始)必须大于或等于零,且小于参数列表的大小