ConstraintLayout作ListView条目布局时底部View被裁剪问题
ListView条目长文本裁剪问题修复
问题现象
需要实现条目高度随内部文本内容长度自动适配的ListView组件,当前使用的条目布局在标题TextView设置较长文本时,底部的描述TextView会出现内容裁剪异常,预期根ConstraintLayout可以随文本内容自动扩展高度,不裁剪子View。
异常效果截图:
问题根因
核心原因是描述TextView的配置引发了垂直方向的测量循环依赖:
tv_notification_desc被设置了android:layout_height="0dp",该值在ConstraintLayout中代表匹配约束尺寸,即View高度由上下约束的边界共同决定;同时该控件配置了app:layout_constraintTop_toBottomOf="@id/tv_notification_title"和app:layout_constraintBottom_toBottomOf="parent"的双向约束,意味着它的高度需要等父布局高度确定后才能计算。- 但根布局高度被设置为
android:layout_height="wrap_content",这类布局的高度需要等所有子View完成测量、计算出所有子View的边界范围后才能确定自身高度,两者形成循环依赖,最终测量结果异常,描述文本被裁剪。
修复方案
仅需要修改tv_notification_desc的两处配置即可,其余布局逻辑不需要调整:
- 将
android:layout_height="0dp"修改为android:layout_height="wrap_content",让该View的高度由自身文本内容决定,不依赖父布局的高度约束。 - 删除
app:layout_constraintBottom_toBottomOf="parent"约束项,保留顶部对齐标题底部、左右对齐标题的约束即可。
额外注意:确认ListView的Adapter逻辑,不要在getView方法中手动给convertView/itemView设置固定高度,保持布局文件中定义的wrap_content高度属性即可。
修复后根布局的minHeight="90dp"会在内容总高度小于90dp时自动撑高条目,未读圆点的垂直居中约束会自动跟随父布局高度调整位置,根布局的16dp内边距也会正常生效,长文本场景下根布局会随标题换行、描述文本位置自动向下扩展,不会出现裁剪。
修复后完整布局代码
<?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" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/background" android:minHeight="90dp" android:padding="16dp"> <ImageView android:id="@+id/iv_notification_thumbnail" android:layout_width="36dp" android:layout_height="36dp" android:src="@drawable/ic_avatar" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:ignore="ContentDescription" /> <TextView android:id="@+id/tv_notification_title" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="8dp" android:fontFamily="@font/roboto" android:text="If the cont" android:textColor="@color/white" android:textSize="14sp" app:layout_constraintEnd_toStartOf="@id/tv_notification_time" app:layout_constraintStart_toEndOf="@id/iv_notification_thumbnail" app:layout_constraintTop_toTopOf="@id/iv_notification_thumbnail" /> <TextView android:id="@+id/tv_notification_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/roboto" android:text="@string/value_place_holder" android:textColor="@color/text_desc" android:textSize="12sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@id/tv_notification_title" /> <TextView android:id="@+id/tv_notification_desc" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:fontFamily="@font/roboto_medium" android:text="@string/submit_to_oms" android:textColor="@color/text_desc" android:textSize="10sp" app:layout_constraintEnd_toEndOf="@id/tv_notification_title" app:layout_constraintStart_toStartOf="@id/tv_notification_title" app:layout_constraintTop_toBottomOf="@id/tv_notification_title" tools:ignore="SmallSp" /> <ImageButton android:id="@+id/ib_unread_dot" android:layout_width="8dp" android:layout_height="8dp" android:background="@drawable/shape_circle_orange" android:clickable="false" android:visibility="visible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" tools:ignore="ContentDescription" /> </androidx.constraintlayout.widget.ConstraintLayout>
内容的提问来源于stack exchange,提问作者Ashish M
相关产品推荐
相关产品推荐

