Android横向TextView切换数量后高度无法动态适配问题求助
问题描述
在Android应用中遇到TextView高度调整问题:
- 选择数量为1时,仅显示“Tamara”视图,显示正常;
- 选择数量为3时,“Tabby”和“Tamara”均正常显示;
- 切回数量1时,视图高度仍保留两者同时显示时的高度,存在多余空间。
相关代码
Kotlin逻辑代码
fun adjust() { // Check if both views are visible val bothViewsVisible = binding.tabbyFrameLayout.isVisible && binding.tamaraFrameLayout.isVisible if (bothViewsVisible) { binding.tamaraMessageTv.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { // Remove the listener to avoid multiple calls binding.tamaraMessageTv.viewTreeObserver.removeOnGlobalLayoutListener(this) // Measure the height of both TextViews val height1 = binding.tamaraMessageTv.height val height2 = binding.tabbyMessageTv.height // Get the maximum height of both TextViews val maxHeight = max(height1, height2) // Set the height of both TextViews to the maximum height binding.tabbyMessageTv.height = maxHeight binding.tamaraMessageTv.height = maxHeight } }) } else { binding.buyNowPayLaterContainer.requestLayout() Log.d("", "layoutHeight:: ${binding.tamaraMessageTv.height}") } }
XML布局代码
<data> </data> <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/dimen_10dp" android:visibility="gone" tools:visibility="visible" android:id="@+id/buyNowPayLaterContainer" android:orientation="horizontal"> <FrameLayout android:id="@+id/tabbyFrameLayout" android:layout_width="0dp" android:layout_height="match_parent" android:minHeight="@dimen/dimen_40dp" android:layout_weight="1"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:background="@drawable/bg_border_grey" android:layout_marginTop="@dimen/dimen_8dp" android:paddingStart="@dimen/dimen_12dp" android:paddingEnd="@dimen/dimen_7dp" android:orientation="vertical"> <androidx.appcompat.widget.AppCompatImageView android:id="@+id/tabbyArrow" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="@+id/tabbyMessageTv" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@+id/tabbyMessageTv" app:srcCompat="@drawable/ic_arrow_with_padding" /> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/tabbyMessageTv" style="@style/Italian_plate_no2_expanded_very_dark_grey_10sp" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="@dimen/dimen_20dp" android:layout_marginBottom="@dimen/dimen_10dp" android:layout_marginEnd="@dimen/dimen_7dp" android:ellipsize="end" android:maxLines="3" android:textSize="@dimen/dimen_12sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/tabbyArrow" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:text="Pay 4 interest-free payments of AED xx.xx, Pay 4 interest-free payments of AED xx.xx" /> </androidx.constraintlayout.widget.ConstraintLayout> <androidx.appcompat.widget.AppCompatImageView android:layout_width="@dimen/dimen_47dp" android:layout_height="@dimen/dimen_20dp" android:layout_marginStart="@dimen/dimen_12dp" android:elevation="@dimen/dimen_6dp" app:srcCompat="@drawable/bg_tabby" /> </FrameLayout> <View android:id="@+id/view" android:layout_width="@dimen/dimen_8dp" android:layout_height="@dimen/dimen_65dp" /> <FrameLayout android:id="@+id/tamaraFrameLayout" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:background="@drawable/bg_white_rounded_tamara_border" android:layout_marginTop="@dimen/dimen_8dp" android:paddingStart="@dimen/dimen_12dp" android:paddingEnd="@dimen/dimen_7dp" android:orientation="vertical"> <androidx.appcompat.widget.AppCompatImageView android:id="@+id/tamaraArrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" app:layout_constraintBottom_toBottomOf="@+id/tamaraMessageTv" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@+id/tamaraMessageTv" app:srcCompat="@drawable/ic_arrow_with_padding" /> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/tamaraMessageTv" style="@style/Italian_plate_no2_expanded_very_dark_grey_10sp" android:layout_width="@dimen/dimen_0dp" android:layout_height="wrap_content" android:layout_marginTop="@dimen/dimen_20dp" android:layout_marginBottom="@dimen/dimen_10dp" android:layout_marginEnd="@dimen/dimen_7dp" android:paddingEnd="@dimen/dimen_2dp" android:textSize="@dimen/dimen_12sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/tamaraArrow" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:text="Pay 4 interest-free payments of AED xx.xx" /> </androidx.constraintlayout.widget.ConstraintLayout> <androidx.appcompat.widget.AppCompatImageView android:layout_width="@dimen/dimen_47dp" android:layout_height="@dimen/dimen_20dp" android:layout_marginStart="@dimen/dimen_12dp" android:id="@+id/tamaraImageView" android:elevation="@dimen/dimen_6dp" app:srcCompat="@drawable/tamara_icon" /> </FrameLayout> </androidx.appcompat.widget.LinearLayoutCompat>
解决方案
问题根源
当两个视图同时显示时,代码直接给TextView设置了固定高度,但切回单视图模式时,没有重置这个固定高度,导致TextView仍保持之前的高度,无法自适应内容,进而让容器保留多余空间。
修复步骤
- 重置TextView高度为自适应:在单视图模式的else分支中,将两个TextView的布局高度重置为
WRAP_CONTENT,让它们重新根据内容计算高度。 - 确保隐藏视图不占空间:隐藏的FrameLayout必须设置为
View.GONE(而非View.INVISIBLE),这样布局会完全移除该视图的空间占用。 - 规范布局参数修改方式:修改布局高度时,应通过
layoutParams而非直接设置height属性,并调用requestLayout()触发重新测量。
修改后的Kotlin代码
fun adjust() { val bothViewsVisible = binding.tabbyFrameLayout.isVisible && binding.tamaraFrameLayout.isVisible if (bothViewsVisible) { binding.tamaraMessageTv.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { binding.tamaraMessageTv.viewTreeObserver.removeOnGlobalLayoutListener(this) val height1 = binding.tamaraMessageTv.height val height2 = binding.tabbyMessageTv.height val maxHeight = max(height1, height2) // 通过layoutParams修改高度,并触发重绘 binding.tabbyMessageTv.layoutParams.height = maxHeight binding.tamaraMessageTv.layoutParams.height = maxHeight binding.tabbyMessageTv.requestLayout() binding.tamaraMessageTv.requestLayout() } }) } else { // 重置TextView高度为自适应 binding.tabbyMessageTv.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT binding.tamaraMessageTv.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT binding.tabbyMessageTv.requestLayout() binding.tamaraMessageTv.requestLayout() // 确保隐藏的FrameLayout设置为GONE,不占用布局空间 if (!binding.tabbyFrameLayout.isVisible) { binding.tabbyFrameLayout.visibility = View.GONE } if (!binding.tamaraFrameLayout.isVisible) { binding.tamaraFrameLayout.visibility = View.GONE } binding.buyNowPayLaterContainer.requestLayout() Log.d("", "layoutHeight:: ${binding.tamaraMessageTv.height}") } }
额外注意事项
- 切换视图可见性时,必须同步调用
adjust()方法,确保布局状态及时更新。 - 检查XML中FrameLayout的默认可见性,避免初始状态导致的布局异常。
内容的提问来源于stack exchange,提问作者Fazal Hussain
相关产品推荐
相关产品推荐

