You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让MvxRecyclerView每行Item高度动态一致(非固定高度)

MvxRecyclerView 每行Item等高实现问题

当前界面效果:
当前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高度,实现动态等高。

  1. 创建自定义布局管理器:
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;
    }
}
  1. 在代码中替换原布局管理器:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:06:55