如何让MvxRecyclerView每行Item高度动态一致(非固定高度)
MvxRecyclerView 每行Item等高实现问题
当前界面效果:
期望实现效果:每行的两个Item高度一致(如第1和第2个等高,第3和第4个等高),采用动态适配内容高度而非固定高度。当前使用wrap_content导致Item高度随CardView内容变化,不符合需求。
现有代码
RecyclerView布局代码:
<MvvmCross.DroidX.RecyclerView.MvxRecyclerView android:id="@+id/recyclerViewSalary" android:layout_width="0dp" android:layout_height="wrap_content" android:nestedScrollingEnabled="false" app:layout_constraintTop_toBottomOf="@id/lblSalary" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:MvxItemTemplate="@layout/cell_tool_cardview" app:MvxBind="ItemClick OpenTool;ItemsSource SalarisToolItems" app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" app:spanCount="2"/>
Item模板布局代码:
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginEnd="@dimen/margin2" android:layout_marginStart="@dimen/margin2" android:layout_marginBottom="@dimen/margin2" android:layout_marginTop="@dimen/margin2" app:cardCornerRadius="@dimen/margin1" app:cardElevation="0dp" app:MvxBind="Visibility Visibility(Available)"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="@dimen/margin4" android:background="@color/lightBlue"> <FrameLayout android:id="@+id/frameLayoutCellTool" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="@dimen/margin5" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"> <ImageView android:id="@+id/imgTool" android:layout_width="wrap_content" android:layout_height="35dp" android:layout_gravity="center" android:scaleType="centerInside" android:tint="@color/blue" app:MvxBind="DrawableName ImageDrawable"/> </FrameLayout> <TextView android:id="@+id/lblTitle" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="@dimen/margin3" android:layout_marginEnd="@dimen/margin3" android:textColor="@color/blue" android:fontFamily="@font/poppins_semibold" android:textSize="@dimen/t4" android:gravity="center" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/frameLayoutCellTool" app:MvxBind="Text Title"/> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:textSize="@dimen/t2" android:gravity="center" android:fontFamily="@font/mulish_regular" android:textColor="@color/blue" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/lblTitle" app:MvxBind="Text SubTitle; Visibility InvertedVisibility(IsEmptySubTitle)"/> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.cardview.widget.CardView>
实现思路
方法一:自定义GridLayoutManager(推荐)
通过自定义GridLayoutManager,在测量阶段记录每行每个Item的高度,找到该行最大高度后统一设置所有Item高度,实现动态等高。
- 创建自定义布局管理器:
public class EqualHeightGridLayoutManager : GridLayoutManager { public EqualHeightGridLayoutManager(Context context, int spanCount) : base(context, spanCount) { } private int[] _itemHeights; public override void OnMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { _itemHeights = new int[SpanCount]; base.OnMeasure(recycler, state, widthSpec, heightSpec); } public override void MeasureChildWithMargins(View child, int widthUsed, int heightUsed) { base.MeasureChildWithMargins(child, widthUsed, heightUsed); int position = GetPosition(child); int column = position % SpanCount; _itemHeights[column] = Math.Max(_itemHeights[column], child.MeasuredHeight); ViewGroup.LayoutParams layoutParams = child.LayoutParameters; layoutParams.Height = _itemHeights[column]; child.LayoutParameters = layoutParams; } }
- 在代码中替换原布局管理器:
var recyclerView = FindViewById<MvxRecyclerView>(Resource.Id.recyclerViewSalary); recyclerView.SetLayoutManager(new EqualHeightGridLayoutManager(this, 2));
方法二:调整Item布局约束
修改Item根布局的高度属性,让内部布局撑满父容器:
- 将CardView的
android:layout_height="wrap_content"改为match_parent - 将内部ConstraintLayout的
android:layout_height="wrap_content"改为match_parent,并添加app:layout_constraintBottom_toBottomOf="parent"
此方法依赖RecyclerView的测量逻辑,部分场景下稳定性不如自定义布局管理器,优先推荐方法一。
内容的提问来源于stack exchange,提问作者haydilen
相关产品推荐
相关产品推荐

