BottomSheetDialog中TextView设置maxLines后无法完整显示文本
BottomSheetDialog内TextView设置maxLines不生效、滚动失效修复
问题表现
在BottomSheetDialog中使用自定义TextView时,即使已经给控件配置maxLines="10"属性,文本仍然无法完整显示,异常效果如下:
相关复现代码
布局文件代码
<com.example.moveapplication.utils.MAFTextView android:id="@+id/tvOwnerAbout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:text="" android:layout_marginEnd="5dp" android:maxLines = "10" android:scrollbars="vertical" android:textColor="@android:color/black" app:layout_constraintBottom_toBottomOf="@+id/icAbout" app:layout_constraintStart_toEndOf="@+id/icAbout" app:layout_constraintTop_toTopOf="@+id/icAbout" tools:text="Agent for Jazzy flats" />
无效的滚动设置代码
uAbout.movementMethod = ScrollingMovementMethod()
自定义TextView实现
class MAFTextView(context: Context, attrs: AttributeSet) : AppCompatTextView (context, attrs){ init { applyFont() } private fun applyFont() { val typeface: Typeface = Typeface.createFromAsset(context.assets, "Montserrat-Regular.ttf") setTypeface(typeface) } }
故障原因
两个问题叠加导致异常:
- 布局写法问题:ConstraintLayout中给TextView同时设置了
layout_height="wrap_content"和上下双向约束,控件测量高度时会被父容器约束强制压缩,maxLines属性根本不会触发,自然没法按10行的上限测量高度。 - 事件拦截问题:BottomSheetDialog的根布局默认会拦截所有纵向滑动的触摸事件,哪怕给TextView设置了
ScrollingMovementMethod,控件也拿不到滑动事件,滚动逻辑完全不生效。
修复步骤
- 修正布局约束:去掉TextView的底部约束,把宽度改成
0dp(匹配约束),增加右侧约束,保证控件测量时不受双向约束挤压,maxLines可以正常生效:<com.example.moveapplication.utils.MAFTextView android:id="@+id/tvOwnerAbout" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginEnd="5dp" android:maxLines="10" android:scrollbars="vertical" android:textColor="@android:color/black" app:layout_constraintTop_toTopOf="@+id/icAbout" app:layout_constraintStart_toEndOf="@+id/icAbout" app:layout_constraintEnd_toEndOf="parent" tools:text="Agent for Jazzy flats" /> - 处理触摸事件冲突:给TextView设置触摸监听,滑动时通知父布局不要拦截事件,保证滚动逻辑可以正常响应:
uAbout.movementMethod = ScrollingMovementMethod() uAbout.setOnTouchListener { view, event -> // 滑动时禁止父布局拦截事件 view.parent.requestDisallowInterceptTouchEvent(true) if (event.actionMasked == MotionEvent.ACTION_UP) { // 手指抬起时恢复父布局拦截能力 view.parent.requestDisallowInterceptTouchEvent(false) } false }
现有自定义TextView仅做了字体替换,没有重写测量、触摸相关逻辑,不需要额外修改。
内容的提问来源于stack exchange,提问作者Sam Kabiru
相关产品推荐
相关产品推荐

