Android:RecyclerView使用GridLayout

2023-02-09  本文已影响0人  因为我的心

一、前言:

需求:我想要GridLayout 左右,上下的间距都是15dp。

如下图:


图片.png

二、解决:

方法:RecyclerView使用GridLayoutManager 设置间距的时候需要重写RecyclerView.ItemDecoration这个类来设置间距。

但由于网格类型下左右都有Item,要想每个item上下左右间距保持一致,单独设置item的间距不太容易实现,这个时候同时设置RecyclerView的Padding值更容易实现。

1、item的布局如下:

//我需要的图片宽高比例:92:125
<?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"
    android:id="@+id/cl_item_type1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/iv_book_pic"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:layout_constraintDimensionRatio="92:125"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/ui_dp_5"
        android:ellipsize="end"
        android:maxLines="2"
        android:text="XXXXXXX"
        android:textColor="@color/black_3"
        android:textSize="@dimen/ui_sp_14"
        app:layout_constraintEnd_toEndOf="@+id/iv_book_pic"
        app:layout_constraintStart_toStartOf="@+id/iv_book_pic"
        app:layout_constraintTop_toBottomOf="@+id/iv_book_pic" />

    <TextView
        android:id="@+id/tv_describe"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/ui_dp_5"
        android:ellipsize="end"
        android:maxLines="1"
        android:text="XXXXXXX"
        android:textColor="@color/gray_9"
        android:textSize="@dimen/ui_sp_12"
        app:layout_constraintEnd_toEndOf="@+id/iv_book_pic"
        app:layout_constraintStart_toStartOf="@+id/iv_book_pic"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />
</androidx.constraintlayout.widget.ConstraintLayout>

2、 ItemTypeProvider1实现:

class ItemTypeProvider1 :
    BaseItemProvider<BaseProviderMultiBean>() {
    override val itemViewType: Int
        get() = HOME_TYPE1
    override val layoutId: Int
        get() = R.layout.item_home_type1

    override fun convert(helper: BaseViewHolder, item: BaseProviderMultiBean) {

        val tvTitle = helper.getView<TextView>(R.id.tv_title)
        val rvList = helper.getView<RecyclerView>(R.id.rv_list)
        if (item is NewBaseLabelBean){
            val label = item.label //推荐位名称
            val list = item.list  //下方数组
            tvTitle.text = label

            val madapter = BookItemType1Adapter()
            val linearLayoutManager = GridLayoutManager(context,3)
            linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
            //设置上方和右方
            rvList.addItemDecoration(SpacesItemDecoration(15))
            //设置左侧距离
            rvList.setPadding(15.dp, 0, 0, 0)
            rvList.layoutManager = linearLayoutManager
            rvList.adapter = madapter
            if (list != null) {
                madapter.data = list
            }
        }
    }
}

这里我用的ConstraintLayout,其实不管用什么,只要保持Item的布局充满屏幕即可。
然后设置RecyclerView的addItemDecoration 以及PaddingLeft值。

//没有添加过再去添加
if (itemDecorationCount<=0){
      //设置上方和右方
      addItemDecoration(SpacesItemDecoration(15))
}
//设置左侧距离
 rvList.setPadding(15.dp, 0, 0, 0)

3、SpacesItemDecoration:

ItemDecoration 类中的代码。只要设置每个Item的右边距就可以,这样既能保持Item大小一致,左右间距也是一致的。

/**
 * GridLayoutManager 设置上右间距一样
 */
class SpacesItemDecoration(val space: Int) : RecyclerView.ItemDecoration() {
    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        if (parent.layoutManager is GridLayoutManager) {
            outRect.top = space.dp
            outRect.right = space.dp
        }
    }
}

其实就是一种思路,如果你的Item不是充满屏幕的,而是固定值得大小。

比如每行3个item。 
item间距 = (屏幕宽度 - item 宽度*3) 除以 (3 + 1)

4、 总结:

1、最重要的是ImageView中xml宽高比例;
2、代码中左右间距适配

  //设置上方和右方
   rvList.addItemDecoration(SpacesItemDecoration(15))
   //设置左侧距离
   rvList.setPadding(15.dp, 0, 0, 0)
5、下面是dp的扩展函数,有需要的取用:
/**
 * 扩展函数
 */
class ExtendUtils {
}

/**
 * 正常编码中一般只会用到 [dp]/[sp] ;
 * 其中[dp]/[sp] 会根据系统分辨率将输入的dp/sp值转换为对应的px
 */
val Float.dp: Float                 // [xxhdpi](360 -> 1080)
    get() = android.util.TypedValue.applyDimension(
        android.util.TypedValue.COMPLEX_UNIT_DIP, this, Resources.getSystem().displayMetrics
    )

val Int.dp: Int
    get() = android.util.TypedValue.applyDimension(
        android.util.TypedValue.COMPLEX_UNIT_DIP,
        this.toFloat(),
        Resources.getSystem().displayMetrics
    ).toInt()


val Float.sp: Float                 // [xxhdpi](360 -> 1080)
    get() = android.util.TypedValue.applyDimension(
        android.util.TypedValue.COMPLEX_UNIT_SP, this, Resources.getSystem().displayMetrics
    )


val Int.sp: Int
    get() = android.util.TypedValue.applyDimension(
        android.util.TypedValue.COMPLEX_UNIT_SP,
        this.toFloat(),
        Resources.getSystem().displayMetrics
    ).toInt()

参考:https://blog.csdn.net/liupengcaho/article/details/117807393

上一篇 下一篇

猜你喜欢

热点阅读