为RecyclerView的不同item项实现不同的布局(添加分类Header)
来源:互联网 发布:windows mail在哪 编辑:程序博客网 时间:2024/05/22 13:36
最近在做一个应用的时候,需要为GridLayoutManager添加头部header,然后自然而然就想到了用不同的itemType去加载不同的布局。
1.实现多item布局,用不同的itemType去加载不同的布局。
主要思路就是先定义好标识itemType的常量,然后重写getItemViewType()方法,根据不同的位置(position)返回不同的Type,接着在onCreateViewHolder()中根据参数viewType去判断该item项应该 inflate 哪个布局文件,并返回相应的ViewHolder实例(这里ViewHolder是根据不同的item布局预先自定义好的不同的ViewHolder)
比如我的代码:
public class MyRecyclerCardviewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ public static enum ITEM_TYPE { ITEM_TYPE_Theme, ITEM_TYPE_Video } //数据集 public List<Integer> mdatas; private TextView themeTitle; public MyRecyclerCardviewAdapter(List<Integer> datas){ super(); this.mdatas = datas; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ITEM_TYPE.ITEM_TYPE_Theme.ordinal()){ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.videothemelist,parent,false); return new ThemeVideoHolder(view); }else if(viewType == ITEM_TYPE.ITEM_TYPE_Video.ordinal()){ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.videocardview,parent,false); return new VideoViewHolder(view); } return null; } @Override public void onBindViewHolder(final ViewHolder holder, final int position) { if (holder instanceof ThemeVideoHolder){ themeTitle.setText("励志"); }else if (holder instanceof VideoViewHolder){ ((VideoViewHolder)holder).videologo.setImageResource(R.drawable.lianzai_02); ((VideoViewHolder)holder).videovname.setText("励志,俄小伙练习街头健身一年的体型变化,Dear Hard Work!"); ((VideoViewHolder)holder).videoviewed.setText("2780次"); ((VideoViewHolder)holder).videocomment.setText("209条"); } } public int getItemViewType(int position){ return position % 5 == 0 ? ITEM_TYPE.ITEM_TYPE_Theme.ordinal() : ITEM_TYPE.ITEM_TYPE_Video.ordinal(); } @Override public int getItemCount() { return mdatas.size(); } public class ThemeVideoHolder extends RecyclerView.ViewHolder{ public ThemeVideoHolder(View itemView) { super(itemView); themeTitle = (TextView) itemView.findViewById(R.id.hometab1_theme_title); } } public class VideoViewHolder extends RecyclerView.ViewHolder { public ImageView videologo; public TextView videovname; public TextView videoviewed; public TextView videocomment; public VideoViewHolder(View itemView) { super(itemView); videologo = (ImageView) itemView.findViewById(R.id.videologo); videoviewed = (TextView) itemView.findViewById(R.id.videoviewed); videocomment = (TextView) itemView.findViewById(R.id.videocomment); videovname = (TextView) itemView.findViewById(R.id.videoname); } }}
但是,当我们把 LayoutManager 改成GridLayoutManager的时候你就出现了不是我们期待的效果,如下图:
What the hell is going on? 什么鬼?怎么添加的header随着其他item项以cell的形式出现在网格上。仔细想一想,发现了下面代码
GridLayoutManager layoutManager = new GridLayoutManager(this,2, GridLayoutManager.VERTICAL,false);
gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return getItemViewType(position) == ITEM_TYPE.ITEM_TYPE_Theme.ordinal() ? gridManager.getSpanCount() : 1; } });
那么,这段代码在自定义Adapter中应该添加在何处呢?放在onAttachedToRecyclerView()中再合适不过了。
public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); if(manager instanceof GridLayoutManager) { final GridLayoutManager gridManager = ((GridLayoutManager) manager); gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return getItemViewType(position) == ITEM_TYPE.ITEM_TYPE_Theme.ordinal() ? gridManager.getSpanCount() : 1; } }); } }
这时就可以实现我想要的效果了,运行效果图如下:
代码我已经抽离出来放到我的Github了:RecycleViewWithHeader
2.最后说一下为什么为什么用RecyclerView取代ListView。
用过ListView的都知道,在ListView中若要复用视图缓存,就要在getView()方法中手动判断convertView是否为空,若不为空则复用视图缓存,若为空则重新加载视图,而RecyclerView相当于对ListView的Adapter进行了再次封装,把ListView手动判断是否有缓存的代码封装到RecyclerView内部,使这部分逻辑不可见,我们只需要通过getItemCount()方法告诉RecyclerView有多少项数据,然后在onCreateViewHolder()中加载item布局实例化ViewHolder,然后在onBindViewHolder()中完成数据的绑定即可。
- 为RecyclerView的不同item项实现不同的布局(添加分类Header)
- 为RecyclerView的不同item项实现不同的布局(添加分类Header)
- RecyclerView之添加不同的item布局
- RecyclerView添加多个样式不同的Item布局
- RecyclerView添加多个样式不同的Item布局
- CoordinatorLayout +RecyclerView+加载不同布局的item
- CoordinatorLayout +RecyclerView+加载不同布局的item
- RecyclerView加载不同item并实现其item点击事件,实现添加常用应用的功能
- 给Recyclerview的item设置不同布局的Adapter
- 实现listView的不同布局item
- ListView实现不同的Item布局
- Android ListView不同的item布局实现
- recyclerview加载不同的布局
- ListView的添加不同布局的item,缓存处理方法
- Android为ListView的Item设置不同的布局
- Android为ListView的Item设置不同的布局
- Android为ListView的Item设置不同的布局
- Android为ListView的Item设置不同的布局
- 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个
- php
- Android官方文档之App Components(Intents and Intent Filters)
- Storm配置项详解:
- CocoaPods中Podfile详解
- 为RecyclerView的不同item项实现不同的布局(添加分类Header)
- 剑指offer面试题 替换空格
- easyui datetimebox 如何只显示 月份,不显示具体的数据
- modbus 协议(1)
- view事件传递
- ubuntu16.04使用手札(二)——分区管理
- D触发器二分频电路
- 求二进制中1的个数----Java实现
- MFC中Spin control的使用