优化RecyclerView item间距 实现按文本长度动态调整列数方案求助
解决方案
你需要的是自动换行的流式标签布局,Android官方提供的FlexboxLayoutManager可以直接满足动态列数的需求,不需要手动计算列宽和排列逻辑,具体实现步骤如下:
1. 引入Flexbox依赖
在模块级build.gradle文件中添加依赖:
dependencies { implementation 'com.google.android.flexbox:flexbox:3.0.0' }
2. 替换RecyclerView的布局管理器
把原来的GridLayoutManager替换为FlexboxLayoutManager,同时做RTL适配和排列配置:
val arr:ArrayList<String> = arrayListOf("English","Intermediate","English","English","arr","UICollectionViewFlowLayoutFlowFlowFlow","English","UICollectionViewDelegate","English","Intermediate","UIViewController","viewDidLoad","Intermediate","String","Intermediate","arr","Intermediate","UIKit","Intermediate","English","columnLayout","English","languageLabel") // 配置Flexbox布局管理器 val flexboxManager = FlexboxLayoutManager(this).apply { // 主轴为横向 flexDirection = FlexDirection.ROW // 超过宽度自动换行 flexWrap = FlexWrap.WRAP // 适配RTL布局,内容从右往左排列 layoutDirection = View.LAYOUT_DIRECTION_RTL // 主轴对齐方式 justifyContent = JustifyContent.FLEX_START // 次轴对齐方式 alignItems = AlignItems.CENTER } recyclerView.layoutManager = flexboxManager // 添加item间距装饰器 recyclerView.addItemDecoration(TagItemDecoration(10.dpToPx())) adaAdapter = CustomAdapter(this, arr) recyclerView.adapter = adaAdapter
注:上面用到的dpToPx()是dp转像素的通用扩展方法,用来适配不同设备的屏幕密度,你也可以直接传入像素值。
3. 修改Item布局,移除固定宽度
把Item布局里的固定宽高配置替换为自适应,删除多余嵌套层级:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/mainL" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp"> <TextView android:id="@+id/typeTv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:textSize="14sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
4. 删除Adapter里的固定宽度逻辑
Adapter不需要再手动计算Item宽度,简化后代码如下:
class CustomAdapter(val context: DreamsActivity, val items: ArrayList<String>) : RecyclerView.Adapter<CustomAdapter.ViewHolderProductList>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolderProductList { val layoutInflater = LayoutInflater.from(parent.context) val cellForRow = layoutInflater.inflate(R.layout.dreams_collection,parent, false) return ViewHolderProductList(cellForRow) } override fun getItemCount(): Int = items.size override fun onBindViewHolder(holder: ViewHolderProductList, position: Int) { holder.typeTv.text = items[position] } inner class ViewHolderProductList(itemView: View) : RecyclerView.ViewHolder(itemView) { var typeTv: TextView = itemView.findViewById(R.id.typeTv) var mainL: ConstraintLayout = itemView.findViewById(R.id.mainL) } }
5. 实现ItemDecoration统一控制间距
自定义装饰器来统一设置Item之间的上下左右间距,适配设计稿要求:
class TagItemDecoration(private val space: Int) : RecyclerView.ItemDecoration() { override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) { outRect.top = space outRect.bottom = space outRect.left = space outRect.right = space } }
如果需要调整间距,直接修改构造参数里的数值即可。
内容的提问来源于stack exchange,提问作者sheko
相关产品推荐
相关产品推荐

