一、前言:
需求:我想要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
网友评论