如何强制停止Scrollable View(如ListView)的滚动?
实现触摸EditText时停止Scrollable View滚动并恢复滚动能力
核心逻辑
当EditText被触摸时,立即中断Scrollable View(如ScrollView、RecyclerView)的当前滚动动作(包括惯性滚动),但保留其后续的滚动能力,不做禁用处理。
针对不同Scrollable View的实现代码
1. 针对ScrollView
EditText editText = findViewById(R.id.target_edittext); ScrollView scrollView = findViewById(R.id.target_scrollview); editText.setOnTouchListener((v, event) -> { if (event.getAction() == MotionEvent.ACTION_DOWN) { // 中断惯性滚动并停止当前滚动 scrollView.fling(0); scrollView.stopScroll(); } // 返回false,确保EditText能正常接收后续触摸事件(获取焦点、输入等) return false; });
2. 针对RecyclerView
EditText editText = findViewById(R.id.target_edittext); RecyclerView recyclerView = findViewById(R.id.target_recyclerview); editText.setOnTouchListener((v, event) -> { if (event.getAction() == MotionEvent.ACTION_DOWN) { // 停止惯性滚动 recyclerView.fling(0, 0); // 中断LayoutManager的滚动动作 if (recyclerView.getLayoutManager() != null) { recyclerView.getLayoutManager().stopScroll(); } } return false; });
3. 自动查找上层滚动视图(适配嵌套布局)
如果EditText嵌套在多层布局中,可通过递归查找上层的Scrollable View:
editText.setOnTouchListener((v, event) -> { if (event.getAction() == MotionEvent.ACTION_DOWN) { ViewParent parent = v.getParent(); // 向上查找目标滚动视图 while (parent != null && !(parent instanceof ScrollView || parent instanceof RecyclerView)) { parent = parent.getParent(); } // 找到后执行停止滚动操作 if (parent instanceof ScrollView) { ((ScrollView) parent).fling(0); ((ScrollView) parent).stopScroll(); } else if (parent instanceof RecyclerView) { ((RecyclerView) parent).fling(0, 0); ((RecyclerView) parent).getLayoutManager().stopScroll(); } } return false; });
关键注意事项
- 不要使用
setEnabled(false)禁用Scrollable View,否则会永久失去滚动能力,我们只需要中断当前滚动动作而非禁用功能。 - 触摸监听器返回
false是为了让EditText正常处理后续事件,避免拦截事件导致EditText无法获取焦点或输入。 - 不同滚动组件的停止方法略有差异,比如ListView可使用
fling(0)或smoothScrollBy(0, 0)实现停止滚动。
内容的提问来源于stack exchange,提问作者Danison Auza Nuñez
相关产品推荐
相关产品推荐

