RecyclerView详细介绍-----多item布局(三)
2016-11-11 21:17
309 查看
1.前言
前面两篇文章主要介绍了recyclerview的基本使用,接下来介绍复杂一点的需求。我们之前用listview的时候肯定遇到itemType>1的时候,我们定义多套item布局,借助getItemViewType()实现多套布局。但是如果像淘宝首页,上面是listview的一个一个item,下面确是一个GridView的话,我们如何实现呢?当然之前有人会把GridView用ListView来实现,及一个Listview的item来代替GridView的两个item,只是数据集我们要自己做处理,总之很麻烦。现在有了recyclerview,这些就变得很简单。
2.实现效果
上图既有listview的列表,下方又有gridview,如何实现呢?
3.具体实现过程:
1)跟listview一样,recyclerview借助getItemViewType(int position)实现多套布局判断,然后根据itemtype实现多套布局的创建跟赋值,具体代码如下:public class MultiItemAdapter extends RecyclerView.Adapter<MultiItemAdapter.ViewHolder> { public static final int ONE_TEXT_VIEW_TYPE = 0; public static final int TWO_TEXT_VIEW_TYPE = 1; public static final int GRID_VIEW_TYP = 2; private ArrayList<Person> data; private Context context; public MultiItemAdapter(Context context, ArrayList<Person> data) { this.data = data; this.context = context; } @Override public int getItemViewType(int position) { if (data.get(position).getType() == ONE_TEXT_VIEW_TYPE) { return ONE_TEXT_VIEW_TYPE; } else if (data.get(position).getType() == TWO_TEXT_VIEW_TYPE) { return TWO_TEXT_VIEW_TYPE; } else if (data.get(position).getType() == GRID_VIEW_TYP) { return GRID_VIEW_TYP; }else { return ONE_TEXT_VIEW_TYPE; } } @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { View itemView = null; switch (viewType) { case ONE_TEXT_VIEW_TYPE: itemView = LayoutInflater.from(this.context).inflate(R.layout.multi_item_one, null); break; case TWO_TEXT_VIEW_TYPE: itemView = LayoutInflater.from(this.context).inflate(R.layout.multi_item_two, null); break; case GRID_VIEW_TYP: itemView = LayoutInflater.from(this.context).inflate(R.layout.multi_item_three, null); break; } return new ViewHolder(itemView); } @Override public void onBindViewHolder(ViewHolder holder, int position) { int itemViewType = getItemViewType(position); switch (itemViewType) { case ONE_TEXT_VIEW_TYPE: showOneTextView(holder, position); break; case TWO_TEXT_VIEW_TYPE: showTwoTextView(holder, position); break; case GRID_VIEW_TYP: showGridView(holder, position); break; } } /** * 赋值 * * @param holder * @param position */ private void showOneTextView(ViewHolder holder, int position) { TextView textview = (TextView) holder.findViewById(R.id.item_text); textview.setText(data.get(position).getName()); } private void showTwoTextView(ViewHolder holder, int position) { TextView item_text_one = (TextView) holder.findViewById(R.id.item_text_one); TextView item_text_two = (TextView) holder.findViewById(R.id.item_text_two); item_text_one.setText(data.get(position).getName()); item_text_two.setText(data.get(position).getType() + ""); } private void showGridView(ViewHolder holder, int position) { TextView textview = (TextView) holder.findViewById(R.id.item_text); textview.setText(data.get(position).getName()); } @Override public int getItemCount() { return data == null ? 0 : data.size(); } //自定义的ViewHolder,持有每个Item的的所有界面元素 public static class ViewHolder extends RecyclerView.ViewHolder { private Map<Integer, View> mCacheView; public ViewHolder(View itemView) { super(itemView); mCacheView = new HashMap<>(); } public View findViewById(int resId) { View view; if (mCacheView.containsKey(resId)) { view = mCacheView.get(resId); } else { view = itemView.findViewById(resId); mCacheView.put(resId, view); } return view; } } }
这里需要说一下,ViewHolder 我们这边统一做了封装,抽出findViewById方法,内部做了缓存处理,而简单的具体实例化交给各个具体item,方便使用。
2)我们知道普通的listview只有一列,而gridview是多列,recyclerview如何做到呢?其实是用到了layoutManager.setSpanSizeLookup方法.
public class MultiItemActivity extends AppCompatActivity { /** * view */ private RecyclerView recyclerView; /** * 用来确定每一个item如何进行排列摆放,何时展示和隐藏 */ private GridLayoutManager layoutManager; /** * 适配器 */ private MultiItemAdapter mAdapter; private ArrayList<Person> data = new ArrayList<Person>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } /** * 初始化布局组件 */ private void initView() { recyclerView = (RecyclerView) findViewById(R.id.recycler_view); //创建默认的线性LayoutManager layoutManager = new GridLayoutManager(this, 2); recyclerView.setLayoutManager(layoutManager); //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能 recyclerView.setHasFixedSize(true); } /** * 初始化数据 */ private void initData() { for (int i = 0; i < 10; i++) { Person person = new Person(); person.setName(i + "abc" + 1); if (i < 3) { person.setType(MultiItemAdapter.ONE_TEXT_VIEW_TYPE); } else if (i < 6) { person.setType(MultiItemAdapter.TWO_TEXT_VIEW_TYPE); } else { person.setType(MultiItemAdapter.GRID_VIEW_TYP); } data.add(person); } //创建并设置Adapter mAdapter = new MultiItemAdapter(this, data); recyclerView.setAdapter(mAdapter); recyclerView.setItemAnimator(new DefaultItemAnimator()); layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { if (mAdapter.getItemViewType(position) == MultiItemAdapter.GRID_VIEW_TYP) { return 1; } else { return 2; } } }); } }
在上面的基本设置中,我们的spanCount为2,setSpanSizeLookup可以让你根据position来设置spanCount,spanCount可以想象成布局里面的weight(比重),原先通过layoutManager = new GridLayoutManager(this, 2);设置成一个item占比为2,那么如果根据setSpanSizeLookup设置的spanCount为1的话,那么一行就是2列,这样才能满足一行的比重为2;如果spanCount为2的话,则说明一行一列。
通过上面的代码,我们就轻松的实现了多itemtype甚至listview跟gridview混合的情况。
4.完整代码下载地址如下所示:
demo下载链接欢迎一起交流讨论
群号:469890293
相关文章推荐
- xml文件里让recyclerview显示item布局
- Android 自定义RecyclerView.ItemDecoration(GridLayoutManager布局下)
- RecyclerView实现多种item布局
- [置顶] RecyclerView实现加载多种条目类型,仿新闻列表多种item布局.
- Recyclerview添加头布局和尾布局、item点击事件详解
- 使用RecyclerView实现两种不同Item布局
- Android中RecyclerView点击item展开列表详细内容(超简单实现)
- RecyclerView Item 布局宽高无效问题探究
- RecyclerView显示Item布局不一致
- Android recyclerview 多个布局 item数据错乱
- RecyclerView 多布局,Item中使用EditText刷新问题扫坑
- Android布局之RecyclerView初级入门介绍及相关教程
- RecyclerView的Item点击事件,增加删除Item瀑布流动画效果,长按拖动Item,RecyclerView复杂布局、实现新闻频道选择器
- Android学习笔记之RecyclerView(二)-异布局Item实现
- ListView、recyclerView的itemView布局注意事项
- 商城之RecyclerView 详细介绍
- RecyclerView 多布局的时候GlideLayoutManger item占位问题
- Android RecyclerView显示不同item布局
- recyclerView的item行高不能随布局变化
- Android:RecyclerView的Item布局在父布局文件设置无效问题