Android,以GridLayoutManager和ImageView为单元格内容的RecyclerView不适合垂直空间

Posted

技术标签:

【中文标题】Android,以GridLayoutManager和ImageView为单元格内容的RecyclerView不适合垂直空间【英文标题】:Android, RecyclerView with GridLayoutManager and ImageView as cell content does not fit the vertical space 【发布时间】:2021-08-19 14:25:16 【问题描述】:

我正在尝试实现一个简单的图像网格。

每个图像的大小相同,问题是如果我缩小图像(例如,如果我设置 spanCount 以便网格布局必须调整图像大小以适应它们)包含图像的“虚拟单元格”不适应图像大小。

在这里您可以看到 spanCount=3 和 spanCount=4 之间的区别。

如果我对 imageView 使用 fitXY 这是结果,因此网格布局管理器会减小单元格宽度但不适合单元格高度。

我的网格布局 xml:

       <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/grid"
            android:layout_
            android:layout_
            app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
            app:spanCount="4"
            tools:itemCount="30"
            tools:listitem="@layout/image_item" />

还有image_item.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/imageView"
    android:layout_
    android:layout_
    android:scaleType="fitCenter"
    tools:srcCompat="@tools:sample/avatars" />

我的目标:

第 1 步:消除列之间的间隙 第 2 步:调整图像大小,使其始终适合水平空间(在此示例中,spanCount = 3,右侧可见一个小空间)

为了更清楚,我需要删除标记为红色的空间。

【问题讨论】:

【参考方案1】:

如果我可以尝试回答这个问题,在您的 image_item.xml 中,我建议您将布局宽度更改为 match_parent 像这样

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/imageView"
    android:layout_
    android:layout_
    android:scaleType="centerCrop"
    tools:srcCompat="@tools:sample/avatars" />

这背后的逻辑是因为我们已经使用了 GridLayout 管理器并且我们的 spanCount 是 4,所以match_parent 的宽度将占据它的所有可用空间,在分配的 spanCount 内。

其次,我觉得centerCrop 会更好。它可以自动调整您的所有图像,而不会显得拉伸。

编辑: 我觉得您可以使用 ConstraintLayout 的魔力完成此操作,您必须按如下方式更新您的image_item.xml

<?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:layout_
    android:layout_>

    <ImageView
        android:id="@+id/imageView"
        android:layout_
        android:layout_
        tools:srcCompat="@tools:sample/avatars"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

这里的逻辑是 0dp 与 GridLayout 有助于您的图像占据任何可用宽度,dimensionRatio 是一个有助于您的宽度和高度匹配。

【讨论】:

感谢您的回答,不幸的是我不能丢失部分图像,因此这不是一个可行的解决方案。我只需要调整“单元格”的高度,这种行为完全出乎我的意料。 @blow 如果只将宽度保持为match_parent 并删除比例类型,怎么样?我觉得这应该可以解决您的问题,除非我有误解。你能在这里澄清一下你的最终目标吗? 我的目标是消除图像之间的黑色间隙,正如您在第二张图像中看到的那样,“行”之间存在空间。 @blow 我已经更新了答案。您可以尝试使用它。据我了解,这应该是您所需要的。 效果很好,谢谢。所以我必须计算的唯一值是基于图像实际大小的app:layout_constraintDimensionRatio,对吧?【参考方案2】:

您似乎受到spanCountItemCount 以及fitCenter 的影响。要解决问题,请执行此操作。

    转到 gridLayoutManager 并在 gridLayoutManager 中指定所需的单元格数。

    打开您的 image_item.xml,将宽度指定为 match_parent,然后您必须指定高度,例如100dp。不要包装内容,因为图像的大小会不同,我们这样做是为了强制单元格的大小相等,以便每个图像都以相同的方式适应。

    在您的 ImageView declare (android:scaleType="centerCrop") 中不要忘记删除 spanCount、ItemCount 和 fitCenter。

现在,如果 Java 端一切正常,这应该可以正常工作。

【讨论】:

以上是关于Android,以GridLayoutManager和ImageView为单元格内容的RecyclerView不适合垂直空间的主要内容,如果未能解决你的问题,请参考以下文章

Android以编程方式设置视图边距

Android:“缩放以填充屏幕”和“拉伸以填充屏幕”

如何以编程方式创建 android 形状背景?

如何在 Android 10 中以编程方式安装任何 Android 应用

*** 以编程方式 android

Android:以编程方式更改选项卡文本颜色