MultiType GridLayoutManager 间距问题

1,799 阅读1分钟
image.png

UI大致长这个样子,图片item之间的间距和文本item之间的间距不是一样的,稍微好一点的就是图片item和文本item到屏幕左右的间距是一样的。

可以通过GridLayoutManager.LayoutParams的getSpanIndex得到这个item在这一行是第几个

//图片item之间横向的间距
val imageSpan = Utils.convertDpToPixel(15f).toInt()

//文字item之间横向的间距
val textSpan = Utils.convertDpToPixel(5f).toInt()

//设置item之间的间距
val itemDecoration = object :ItemDecoration(){
    override fun getItemOffsets(outRect: Rect,view: View,parent: RecyclerView,state: RecyclerView.State) {
        super.getItemOffsets(outRect, view, parent, state)
        val position = parent.getChildAdapterPosition(view)
        if(position >= 0 && position<items.size){
            val item = items[position]
            if(item is TextBean){//文字的item
                if (parent.layoutManager is GridLayoutManager) {
                    val spanIndex = (view.layoutParams as GridLayoutManager.LayoutParams).spanIndex
                    val spanSize = (view.layoutParams as GridLayoutManager.LayoutParams).spanSize
                    //item在该行是第几个
                    val indexInRow = spanIndex / spanSize
                    val spanCount = 4

                    outRect.left = indexInRow * textSpan / spanCount
                    outRect.right = textSpan - (indexInRow + 1) * textSpan / spanCount
                    outRect.bottom = Utils.convertDpToPixel(5f).toInt()
                }
            }else if(item is ImageBean){//图片的item
                if (parent.layoutManager is GridLayoutManager) {
                    val spanIndex = (view.layoutParams as GridLayoutManager.LayoutParams).spanIndex
                    val spanSize = (view.layoutParams as GridLayoutManager.LayoutParams).spanSize
                    //item在该行是第几个
                    val indexInRow = spanIndex / spanSize
                    val spanCount = 3

                    outRect.left = indexInRow * imageSpan / spanCount
                    outRect.right = imageSpan - (indexInRow + 1) * imageSpan / spanCount
                    outRect.bottom = Utils.convertDpToPixel(20f).toInt()
                }
            }else{//标题
                outRect.bottom = Utils.convertDpToPixel(20f).toInt()
            }
        }
    }
}

这个Image的item是正方形的,通过ConstraintLayout的layout_constraintDimensionRatio属性设置为1:1

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/thumbIv"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        android:src="@mipmap/ic_place_holder"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

每行的item的outRect.left+outRect.right要相等,要不然会出现item的宽度不一致,因为item的宽度是 recyclerView的宽度除以每一行的spanCount然后在减去outRect.left和outRect.right,如果这一行每个item的outRect.left outRect.right之和不相等,就会出现item的宽度不一致了。

最后感谢: stackoverflow.com/questions/2…