将偏移应用于 GridLayout 项目并在所有项目之间保持相同的大小

Apply offset to GridLayout items and preserve equal size among all items

我想在网格中的项目之间创建一个 space。这些项目应该都相等 width/height.

我试过的:

创建一个 GridLayoutOffsetDecorator 将偏移应用于所有网格项目:

class GridLayoutOffsetDecorator(var offset: Int) : RecyclerView.ItemDecoration() {

    override fun getItemOffsets(
            outRect: Rect,
            view: View,
            parent: RecyclerView,
            state: RecyclerView.State?) {

        super.getItemOffsets(outRect, view, parent, state)

        outRect.set(offset, offset, offset, offset)
    }
}

具有 8dp 的偏移量会在项目之间创建 16dp space。所以我们仍然需要对外边缘应用 8dp 的填充:

<android.support.v7.widget.RecyclerView
        android:id="@+id/productList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:padding="8dp" />

结果是:

问题: 项目大小不等:

当您查看蓝线时,您会注意到高度略有不同。只有在填充 recyclerview 后才会出现这种差异。此填充似乎稍微调整了一些项目的大小。你们有解决这个问题的经验吗?知道如何解决这个问题吗?


通过从项目中删除图像,高度差消失。图片是这样设置的:

<SquareImageView
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    app:imageResource="@{product.image}" />

SquareImageView:

class SquareImageView : ImageView {

    constructor(context: Context) : super(context)
    constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
    constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, widthMeasureSpec)
    }
}

所以问题可能是图片本身引起的。

能否请您尝试将 imageview 高度设置为固定值。

我在使用 GridLayoutManager 时遇到了同样的问题。通过在适配器中设置图像的宽度和高度来解决它。 这是我的解决方案,希望对您有所帮助。

这就是我在布局中放置 ImageView 的方式。

<LinearLayout
     android:id="@+id/layoutImageProduct"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:gravity="center"
     tools:minHeight="100dp"
     tools:minWidth="150dp">

       <ImageView
           android:id="@+id/imageProduct"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:scaleType="fitCenter"
           android:src="@drawable/placeholder_product"/>
</LinearLayout>

然后在父布局上应用 LayoutParamsImageView

//Setting View width/height
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.layoutImageProduct.getLayoutParams();
params.width = (int) ResourcesUtils.getColumnWidth(context);
params.height = ((int) (ResourcesUtils.getColumnWidth(context)));
holder.layoutImageProduct.setLayoutParams(params);

params = (LinearLayout.LayoutParams) holder.imageProduct.getLayoutParams();
params.width = (int) ResourcesUtils.getColumnWidth(context);
params.height = (int) ResourcesUtils.getColumnWidth(context);
holder.imageProduct.setLayoutParams(params);

这是 getWidth 方法。

public static float getColumnWidth(Context context) {
        if (GRID_COLUMN_WIDTH == -1) {
            int screenWidth = getDisplayMetrics(context).widthPixels;
            float horizontalPadding = getDimensInPixel(context, R.dimen.activity_horizontal_margin);
            // NUM OF COLUMN = 2
            GRID_COLUMN_WIDTH = screenWidth / 2 - horizontalPadding * 2;
        }

        return GRID_COLUMN_WIDTH;
    }

查看屏幕截图,一张带有占位符,一张带有图片。