当前位置:   article > 正文

RecyclerView多种布局排布_androidrecyclerview多布局

androidrecyclerview多布局

        事情是由工作中的一个新项目里的一个页面里的频繁改需求引起的,原来只是不同布局,上下滚动,没有类似网格排布的UI,所以我用ScrollView写的,里面包ConstraintLayout,没有问题,滚动丝滑。后面需求改了,有个地方是列表,塞一个RecyclerView进去,没问题,滚动依旧丝滑。后面,又加另一个列表,再塞一个RecyclerView进去,滚动依旧丝滑,但是,发现这个RecyclerView只显示几个item,后面的不显示了,我还各种断点查看列表数据源和Adapter是不是有问题,结果是没问题,然后给RecyclerView设置一个超大的高度,列表就显示完全了,看来还是RecyclerView嵌套在ScrollerView的问题。后面百度了一下,在RecyclerView外包一层RelativeLayout,显示就完整了,滚动也没问题。开开心心提测,后面,发现列表数据量多的时候,整个页面ANR了。

        怎么办呢?重构页面肯定是要的,普通办法是一个RecyclerView根据类型加载对应的ViewHolder,一想起来,好麻烦,心累。但是,现在可是2023年啊,有没有可能谷歌给了新的api呢?jetpack都重构了安卓框架,总该给点新花样吧?果然是有的,就是ConcatAdapter(据说是RecyclerView1.2.0开始有的,之前是另外的名字,但是功能是一样的),就是把多个Aapter整合到一块。然后就跟ArrayList一样add添加Adapter,UI就根据添加顺序显示,adapter各管各的UI和数据,耦合性大大降低。

        使用也是超级简单,RecyclerView直接setAdapter()把ConcatAdapter添加进去,然后再把不同布局的adapter添加进去,最后concatAdapter.notifyDataSetChanger()即可。

        由于我用的是Jetpack+Kotlin,mvvm是github大佬在Jetpack基础上封装的,我的写法特别简单,可能对应不上你们的代码,仅做参考。

xml布局只需传ConcatAdapter进去,设置滚动方向就好,不需要设置item布局:

  1. <androidx.recyclerview.widget.RecyclerView
  2. android:layout_width="0dp"
  3. android:layout_height="0dp"
  4. android:layout_marginTop="46dp"
  5. android:layout_marginBottom="53dp"
  6. adapter="@{adapter}"
  7. app:layoutManager="com.kunminx.binding_recyclerview.layout_manager.WrapContentLinearLayoutManager"
  8. android:orientation="vertical"
  9. app:layout_constraintLeft_toLeftOf="parent"
  10. app:layout_constraintRight_toRightOf="parent"
  11. app:layout_constraintTop_toTopOf="parent"
  12. app:layout_constraintBottom_toBottomOf="parent"/>

如果里面的子布局仅仅是标题,列表的头部ui,这种简单layout,且不需要更新数据,它的adapter也非常简单,areItemsTheSame和areContentsTheSame都是为true,刷新列表的时候不更新,不然会闪烁一下。

  1. class OrderListHeadAdapter @JvmOverloads constructor(
  2. context: Context,
  3. layout: Int = R.layout.adapter_orde_list_head,
  4. onItem:DiffUtil.ItemCallback<Int> = object : DiffUtil.ItemCallback<Int>(){
  5. override fun areItemsTheSame(oldItem: Int, newItem: Int) = true
  6. override fun areContentsTheSame(oldItem: Int, newItem: Int) = true
  7. }
  8. ):SimpleDataBindingAdapter<Int,AdapterOrdeListHeadBinding>(context,layout,onItem){
  9. override fun onBindItem(
  10. binding: AdapterOrdeListHeadBinding?,
  11. item: Int?,
  12. holder: RecyclerView.ViewHolder?
  13. ) {}
  14. }

添加这个adapter的时候,一定要传个list,而且长度不为0,所以adapter的数据类型使用Int还是比较方便的,使用其他类型也可以。

concatAdapter.addAdapter(OrderListHeadAdapter(requireContext()).apply { submitList(mutableListOf(0)) })

列表部分也是一样,平时普通的该咋设置咋设置,再创建添加进去即可。添加完了记得刷新

concatAdapter.notifyDataSetChanged()

清空列表,只能遍历remove掉adapter,目前没找到合适的api。

比切换ViewHolder方便太多,耦合性大大降低。

       

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/174904
推荐阅读
相关标签
  

闽ICP备14008679号