Как использовать GridLayoutManager в RecyclerView на Android

#android #kotlin #android-recyclerview

#Android #kotlin #android-recyclerview

Вопрос:

В моем приложении у меня есть recyclerView , и для этого я должен использовать GridLayoutManager и устанавливать 2 элемента на столбец.

Я хочу, чтобы эти 2 элемента соответствовали размеру экрана, каждый элемент прилипал к экрану. Например, изображение ниже:

введите описание изображения здесь

Я пишу приведенные ниже коды, но после запуска приложение показывает мне такие, как это:

введите описание изображения здесь

И я хочу установить 120dp для layout_width и layout_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
}
 

Как я могу исправить эту проблему?

Ответ №1:

Это сложно, потому что вам нужна разная плотность макета для каждого элемента, в зависимости от столбца. Я думаю, что это должно быть задано в 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, и вам не нужно ничего делать в адаптере.