动态操作后 GridLayoutManager 中的项目高度

问题描述 投票:0回答:1

我有一个 RecyclerView 和 GridLayoutManager 有 2 列。项目已填充 DiffUtil,到目前为止一切正常。 这些项目由图像(始终相同的高度)和文本组成,文本的长度可能不同,因此具有动态高度。

GridLayoutManager 似乎以相同的高度排列行中的每个项目。但一旦它们改变行,它就不会重新计算它们 -> 只要它们当前可见,单元格的高度就保持静态。

示例:总共 6 项。

 A | B
 C | D 
 E | F 

因此,如果项目 E 有一个短文本,比如说高度 100,而项目 F 有一个长文本,高度 500,那么这两个项目的高度似乎都是 500。

如果项目 B 被删除,E 会将行从 3 更改为 2,但高度仍然为 500,而项目 D 可能只有 150。E 的高度为“350 太多”。 这会产生一种奇怪的外观,因为第 2 行和第 3 行之间有很多空白...

一旦滚动(=这些项目不再可见)向后滚动,一切都会再次正常测量。

如何解决这个问题?

感谢您的帮助。

更新:

item.xml:

    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
<LinearLayout
    android:id="@+id/items_folder_item_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:focusable="true"
    android:paddingTop="15dp"
    android:paddingStart="10dp"
    android:paddingEnd="10dp"
    android:paddingBottom="15dp"
    android:background="?android:attr/selectableItemBackground"
    android:orientation="horizontal">
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_weight="1">
        <RelativeLayout
            android:layout_width="127dp"
            android:id="@+id/items_folder_item_folder_container"
            android:layout_gravity="center_horizontal"
            android:layout_height="127dp">
            <ImageView
                android:id="@+id/items_folder_item_folder"
                android:layout_width="127dp"
                android:layout_height="127dp"
                android:src="@{folder.homeFolder ? (folder.homeIconType == 1 ? @drawable/ic_ordner_weis : (folder.homeIconType == 2 ? @drawable/ic_navi_bons : @drawable/ic_home_grey_48px)) : @drawable/ic_ordner_weis }"
                android:tint="@{folder.folderColorCode}"
                android:contentDescription="@null" />

            <ImageView
                android:layout_width="17dp"
                android:layout_height="17dp"
                android:contentDescription="@null"
                android:layout_alignParentBottom="true"
                android:layout_marginBottom="30dp"
                android:layout_marginStart="24dp"
                android:visibility="@{item.selectionMode ? selectedFolders.contains(item)  View.GONE : View.VISIBLE : View.GONE}"
                android:src="@drawable/ic_item_selection_placeholder" />

            <ImageView
                android:layout_width="27dp"
                android:layout_height="27dp"
                android:contentDescription="@null"
                android:layout_alignParentBottom="true"
                android:layout_marginBottom="27dp"
                android:layout_marginStart="22dp"
                android:visibility="@{selectedFolders.contains(item) == true ? View.VISIBLE : View.GONE}"
                android:src="@drawable/ic_item_selected" />

        </RelativeLayout>

        <LinearLayout
            android:id="@+id/items_folder_item_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="10dp"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:orientation="horizontal">

                <ImageView
                    android:layout_width="16dp"
                    android:layout_height="16dp"
                    android:layout_marginEnd="9dp"
                    android:layout_gravity="center_vertical"
                    android:src="@{item.item.visibleToContact ? @drawable/ic_shared : @drawable/ic_shared_in_progress}"
                    android:visibility="@{item.item.itemPermitted ? View.VISIBLE : View.GONE}"
                    android:contentDescription="@null" />

                <ImageView
                    android:layout_width="16dp"
                    android:layout_height="16dp"
                    android:layout_marginEnd="7dp"
                    android:layout_gravity="center_vertical"
                    android:visibility="@{folder.folderIsFavorite == true ? View.VISIBLE : View.GONE}"
                    android:src="@drawable/ic_favorite_set"
                    android:contentDescription="@null" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center_horizontal"
                    style="@style/ItemNameGrid"
                    android:textColor="@{selectedFolders.contains(item) ? @color/gridItemSelectedTextColor : @color/brownGreyText}"
                    android:text="@{folder.folderName}" />
            </LinearLayout>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:visibility="@{folder.homeFolder ? View.GONE : View.VISIBLE}"
                style="@style/ItemInfoTextGrid"
                android:textColor="@{selectedFolders.contains(item) ? @color/gridItemSelectedTextColor : @color/bluishGreyText}"
                android:text='@{folder.folderItemCount == 1 ? String.format(@string/items_item_element, folder.folderItemCount) : String.format(@string/items_item_elements, folder.folderItemCount) }' />

        </LinearLayout>
    </LinearLayout>

    <RelativeLayout
        android:id="@+id/items_folder_item_more_container"
        android:layout_width="37dp"
        android:clickable="true"
        android:focusable="true"
        android:layout_gravity="bottom"
        android:visibility="@{inChoosingMode ? folder.homeFolder ? View.INVISIBLE : View.VISIBLE : item.selectionMode ? View.INVISIBLE : View.VISIBLE}"
        android:layout_height="37dp">

        <ImageView
            android:layout_width="27dp"
            android:layout_height="27dp"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            android:background="?selectableItemBackgroundBorderless"
            android:src="@{inChoosingMode ? @drawable/ic_arrow_right : @drawable/ic_more}"
            android:contentDescription="@null" />

    </RelativeLayout>

</LinearLayout>
</RelativeLayout>

RecyclerView布局:

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp"
android:background="@color/defaultBackgroundColor"
android:id="@+id/items_root">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    android:layout_width="match_parent"
    android:id="@+id/items_refresh_layout"
    android:layout_height="match_parent">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/items_content">


            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginEnd="22dp"
                android:layout_marginTop="20dp"
                android:layout_marginStart="22dp"
                android:id="@+id/items_topbar">

                <com.fm.atmin.controls.sortfilter.sort.SortControl
                    android:id="@+id/items_topbar_sort_control"
                    android:layout_width="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_height="wrap_content" />

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:clickable="true"
                    android:background="?android:attr/selectableItemBackground"
                    android:layout_alignParentEnd="true"
                    android:id="@+id/items_view_mode_container"
                    android:focusable="true">

                    <ImageView
                        android:id="@+id/items_view_mode"
                        android:layout_width="27dp"
                        android:layout_height="27dp"
                        android:src="@drawable/ic_view_module_grid"
                        />
                </LinearLayout>

            </RelativeLayout>

            <androidx.recyclerview.widget.RecyclerView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/items_recyclerview"
                android:layout_below="@id/items_topbar"
                android:layout_marginTop="25dp" />
        </RelativeLayout>
        <include
            layout="@layout/items_no_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"/>

        <include
            layout="@layout/no_network_layout"
            android:visibility="gone"/>
    </RelativeLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
java android android-recyclerview rows gridlayoutmanager
1个回答
0
投票

我遇到了同样的问题;通过向

RecyclerView.Adapter.onBindViewHolder
添加一些代码来修复它。

override fun onBindViewHolder(holder:ItemVH,position:Int)
{
    // do the binding
    ......

    // after binding item to view holder, request UI to re-layout items
    holder.itemView.requestLayout()
}

参见 requestLayout() 的文档

当某些内容发生更改导致该视图的布局无效时调用此方法。这将安排视图树的布局过程。当视图层次结构当前位于布局传递 (isInLayout() 中时,不应调用此方法。如果正在发生布局,则可能会在当前布局传递结束时(然后布局将再次运行)或在当前布局传递之后接受请求。绘制框架并进行下一个布局。

重写此方法的子类应调用超类方法以正确处理可能的 request-during-layout 错误。

如果重写此方法,则必须调用超类实现。

© www.soinside.com 2019 - 2024. All rights reserved.