Android开发中如何解决ScrollView嵌套CodeView时CodeView区域无法滚动问题
问题原因
CodeView内部封装了可滚动的RecyclerView组件,默认会拦截竖向触摸事件,和外层ScrollView产生滚动冲突,导致触摸CodeView区域时无法触发整个页面的滚动。
解决方案
方案1:通用适配方案(推荐)
在CodeView初始化代码中添加触摸事件监听,滑动时通知父布局接管触摸事件即可:
// Kotlin 实现 val codeViewXml = findViewById<CodeView>(R.id.code_view_xml) val codeViewItem = findViewById<CodeView>(R.id.code_view_item) val scrollFixTouchListener = View.OnTouchListener { v, event -> if (event.action == MotionEvent.ACTION_MOVE) { v.parent.requestDisallowInterceptTouchEvent(false) } false } codeViewXml.setOnTouchListener(scrollFixTouchListener) codeViewItem.setOnTouchListener(scrollFixTouchListener)
Java版本实现:
// Java 实现 CodeView codeViewXml = findViewById(R.id.code_view_xml); CodeView codeViewItem = findViewById(R.id.code_view_item); View.OnTouchListener scrollFixTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_MOVE) { v.getParent().requestDisallowInterceptTouchEvent(false); } return false; } }; codeViewXml.setOnTouchListener(scrollFixTouchListener); codeViewItem.setOnTouchListener(scrollFixTouchListener);
方案2:保留CodeView横向滚动能力
如果代码片段较长需要支持横向滚动,可通过判断滑动方向分别处理事件:
private var lastTouchX = 0f private val scrollFixTouchListener = View.OnTouchListener { v, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { lastTouchX = event.x v.parent.requestDisallowInterceptTouchEvent(true) } MotionEvent.ACTION_MOVE -> { val xOffset = Math.abs(event.x - lastTouchX) val touchSlop = ViewConfiguration.get(v.context).scaledTouchSlop // 横向滑动超过阈值则交由CodeView处理,否则交由父ScrollView处理 v.parent.requestDisallowInterceptTouchEvent(xOffset > touchSlop) } MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { v.parent.requestDisallowInterceptTouchEvent(false) } } false }
可选XML配置优化
如果不需要CodeView自适应高度,也可以直接在XML中设置固定高度并关闭嵌套滚动属性解决冲突:
<io.github.kbiakov.codeview.CodeView android:id="@+id/code_view_xml" android:layout_marginTop="7dp" android:layout_width="match_parent" android:layout_height="220dp" android:nestedScrollingEnabled="false"/>
小提示:建议把CodeView的layout_width属性改为match_parent,避免代码内容过宽超出屏幕显示范围
内容的提问来源于stack exchange,提问作者Amit Swami
相关产品推荐
相关产品推荐

