You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestedScrollView嵌套RecyclerView的CardView中可滚动日志实现失败求助

解决NestedScrollView内RecyclerView的CardView中错误日志的滚动问题

我太懂你碰到的这个糟心问题了——在NestedScrollView嵌套RecyclerView的场景下,CardView里的小滚动容器(比如用来展示日志的TextView)总是拿不到触摸事件,之前试的几种方法没效果,核心原因就是外层滚动容器会拦截触摸事件,导致内层的滚动控件完全没法工作。

下面给你两个亲测有效的解决方案,直接照搬就能用:

方案一:自定义可请求不拦截事件的TextView

我们可以给TextView加个触摸事件处理,让它在被触摸时主动告诉父容器“别抢我的事件,我要自己处理滚动”:

1. 自定义ScrollableTextView类

class ScrollableTextView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : AppCompatTextView(context, attrs, defStyleAttr) {

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        // 关键代码:请求父容器不要拦截当前触摸事件
        parent.requestDisallowInterceptTouchEvent(true)
        return super.onTouchEvent(event)
    }
}

2. 布局文件中使用这个自定义TextView

<com.yourpackage.ScrollableTextView
    android:id="@+id/errorLog"
    android:layout_width="match_parent"
    android:layout_height="120dp"
    android:fontFamily="monospace"
    android:scrollbars="vertical" />

3. 代码中设置滚动方法

errorLog.movementMethod = ScrollingMovementMethod()

方案二:用自定义ScrollView包裹TextView

如果你更倾向于用ScrollView来实现滚动,同样需要给ScrollView加上事件拦截的逻辑:

1. 自定义ScrollableScrollView类

class ScrollableScrollView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ScrollView(context, attrs, defStyleAttr) {

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        parent.requestDisallowInterceptTouchEvent(true)
        return super.onTouchEvent(event)
    }

    override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
        parent.requestDisallowInterceptTouchEvent(true)
        return super.onInterceptTouchEvent(event)
    }
}

2. 布局文件中使用这个自定义ScrollView

<com.yourpackage.ScrollableScrollView
    android:layout_width="match_parent"
    android:layout_height="120dp">

    <TextView
        android:id="@+id/errorLog"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="monospace" />
</com.yourpackage.ScrollableScrollView>

为什么之前的方法失效?

NestedScrollView和RecyclerView本身都是滚动容器,Android的触摸事件传递是从父到子的,当你触摸内层的小滚动控件时,外层的NestedScrollView会先把事件拦截下来处理自身的滚动,导致内层控件根本拿不到事件,自然没法滚动。通过requestDisallowInterceptTouchEvent(true),我们强制让父容器放弃事件拦截,把控制权交还给内层的滚动控件。

内容的提问来源于stack exchange,提问作者LutfiTekin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 09:12:40