首页 > 解决方案 > 如何在 Android 上的 RecyclerView 中使用 GridLayoutManager

问题描述

在我的应用程序中recyclerView,我应该为此使用GridLayoutManager并设置每列 2 个项目。

我想设置这 2 个项目适合屏幕,每个项目都粘在屏幕上。比如下图:

在此处输入图像描述

我写了下面的代码,但在运行应用程序后显示如下

在此处输入图像描述

我想为and设置120dplayout_widthlayout_height

我的 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:id="@+id/rowMasterQuestion_root"
    android:layout_width="@dimen/_120mdp"
    android:layout_height="@dimen/_120mdp"
    android:background="@drawable/gray_border">

    <TextView
        android:id="@+id/rowMasterQuestion_title"
        android:layout_width="@dimen/_120mdp"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/_15mdp"
        android:gravity="center_horizontal"
        android:textColor="@color/black"
        android:textSize="@dimen/_9font_mdp"
        android:visibility="visible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/rowMasterQuestion_answer"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/_15mdp"
        android:layout_marginLeft="@dimen/_10mdp"
        android:layout_marginRight="@dimen/_10mdp"
        android:layout_marginBottom="@dimen/_20mdp"
        android:gravity="center"
        android:paddingLeft="@dimen/_5mdp"
        android:paddingRight="@dimen/_5mdp"
        android:textColor="@color/white"
        android:textSize="@dimen/_8font_mdp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

我的活动代码:

requestMain_childList.apply {
            layoutManager = GridLayoutManager(this@RequestMainPage, 2, GridLayoutManager.VERTICAL, false)
            hasFixedSize()
            adapter = masterChildAdapter
}

我该如何解决这个问题?

标签: androidkotlinandroid-recyclerview

解决方案


这很棘手,因为您希望每个项目具有不同的布局重力,具体取决于列。我认为必须在RecyclerView.Adapter.onBindViewHolder函数中进行设置。

首先,将项目视图的 ConstraintLayout 包装在 FrameLayout 中。设置外部 FrameLayout 的宽度,match_parent使其填充 RecyclerView 中的列。您还可以为 FrameLayout 提供您希望将项目远离屏幕两侧的开始/结束填充量。

<FrameLayout 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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingStart="16dp"
    android:paddingEnd="16dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/wrappedView"
        android:layout_width="@dimen/_120mdp"
        android:layout_height="@dimen/_120mdp"
        ...>

    ...

    </androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

然后在 中onBindViewHolder,您可以根据它所在的列(偶数或奇数数据位置)将内部视图的重力设置为向左或向右。

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        // ...
        val innerView = holder.wrappedView // or however you have it stored in view holder
        (innerView.layoutParams as FrameLayout.LayoutParams).gravity = Gravity.CENTER_VERTICAL or 
                (if (position % 2 == 0) Gravity.START else Gravity.END)
    }

请注意,如果您希望项目在它们的列中居中,这要容易得多。您可以center在 XML 中设置内部视图的重力,而无需在适配器中执行任何操作。


推荐阅读