美文网首页
Android:RecyclerView使用GridLayout

Android:RecyclerView使用GridLayout

作者: 因为我的心 | 来源:发表于2023-02-09 11:39 被阅读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

    相关文章

      网友评论

          本文标题:Android:RecyclerView使用GridLayout

          本文链接:https://www.haomeiwen.com/subject/sfnckdtx.html