如何让BottomSheetDialogFragment内的TextView可滚动且保留滑动功能
解决BottomSheetDialogFragment中TextView滚动触发弹窗关闭的问题
问题原因
给TextView设置ScrollingMovementMethod后,TextView的垂直滑动事件会被BottomSheet的滑动拦截逻辑优先捕获,导致无法正常滚动TextView,反而触发BottomSheet关闭。
解决方案
方法一:自定义TextView处理触摸事件
创建自定义TextView,在滚动时主动阻止父布局拦截触摸事件:
public class ScrollableTextView extends androidx.appcompat.widget.AppCompatTextView { public ScrollableTextView(Context context) { super(context); init(); } public ScrollableTextView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ScrollableTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { setMovementMethod(new ScrollingMovementMethod()); } @Override public boolean onTouchEvent(MotionEvent event) { // 当TextView可上下滚动时,禁止父布局拦截触摸事件 if (canScrollVertically(1) || canScrollVertically(-1)) { getParent().requestDisallowInterceptTouchEvent(true); // 抬手时恢复父布局的拦截权限 if (event.getAction() == MotionEvent.ACTION_UP) { getParent().requestDisallowInterceptTouchEvent(false); } } return super.onTouchEvent(event); } }
布局中替换为自定义TextView:
<com.yourpackage.ScrollableTextView android:id="@+id/your_textview_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:maxHeight="250dp" android:scrollbars="vertical"/>
方法二:给BottomSheet根布局设置触摸监听
在BottomSheetDialogFragment的onViewCreated方法中,拦截BottomSheet的触摸事件:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); TextView textView = view.findViewById(R.id.your_textview_id); textView.setMovementMethod(new ScrollingMovementMethod()); // 获取BottomSheet的根布局 View bottomSheet = requireDialog().findViewById(com.google.android.material.R.id.design_bottom_sheet); if (bottomSheet != null) { bottomSheet.setOnTouchListener((v, event) -> { // 仅当触摸TextView且TextView可滚动时,阻止父布局拦截 if (textView.isPressed() && (textView.canScrollVertically(1) || textView.canScrollVertically(-1))) { v.getParent().requestDisallowInterceptTouchEvent(true); if (event.getAction() == MotionEvent.ACTION_UP) { v.getParent().requestDisallowInterceptTouchEvent(false); } } return false; }); } }
注意事项
- 必须给TextView设置
android:maxHeight或固定高度,同时加上android:scrollbars="vertical",确保TextView具备滚动条件。 - 避免给TextView的父布局设置滑动相关属性,防止多重事件冲突。
内容的提问来源于stack exchange,提问作者optimus
相关产品推荐
相关产品推荐

