我有一个 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>
我遇到了同样的问题;通过向
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()
}
当某些内容发生更改导致该视图的布局无效时调用此方法。这将安排视图树的布局过程。当视图层次结构当前位于布局传递 (isInLayout() 中时,不应调用此方法。如果正在发生布局,则可能会在当前布局传递结束时(然后布局将再次运行)或在当前布局传递之后接受请求。绘制框架并进行下一个布局。
重写此方法的子类应调用超类方法以正确处理可能的 request-during-layout 错误。
如果重写此方法,则必须调用超类实现。