You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android Kotlin中触摸指定View(如TradingView图表)时如何禁用页面滚动?

触摸特定View时禁用ScrollView滚动(解决TradingView图表滚动不流畅问题)

嘿,这个问题我之前做TradingView嵌入ScrollView的时候也踩过坑!本质就是要让ScrollView在触摸到图表的时候“放手”,别抢触摸事件,这样图表就能自己处理X/Y轴的滚动了。下面给你两个实用的Kotlin实现方案:

方案一:自定义ScrollView(推荐,逻辑更清晰)

我们可以自己写个ScrollView的子类,重写事件拦截的方法,判断当前触摸的是不是目标图表,如果是就不拦截事件,让图表自己处理。

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

    private var targetView: View? = null

    // 传入需要禁用ScrollView滚动的目标View(比如你的TradingView图表)
    fun setTargetView(view: View) {
        this.targetView = view
    }

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        targetView?.let { chartView ->
            // 获取图表在屏幕上的坐标范围
            val location = IntArray(2)
            chartView.getLocationOnScreen(location)
            val chartLeft = location[0]
            val chartTop = location[1]
            val chartRight = chartLeft + chartView.width
            val chartBottom = chartTop + chartView.height

            // 判断当前触摸点是不是在图表范围内
            val touchX = ev.rawX.toInt()
            val touchY = ev.rawY.toInt()
            val isTouchOnChart = touchX in chartLeft..chartRight && touchY in chartTop..chartBottom

            // 如果触摸在图表上,就不拦截事件,让图表自己处理滚动
            if (isTouchOnChart) {
                return false
            }
        }
        // 其他情况正常让ScrollView处理滚动
        return super.onInterceptTouchEvent(ev)
    }
}

然后在你的Fragment/Activity里这么用:

// 先找到自定义ScrollView和TradingView图表实例
val scrollView = view.findViewById<CustomScrollView>(R.id.your_scroll_view)
val tradingChart = view.findViewById<View>(R.id.your_trading_view_chart)

// 设置目标View,这样触摸图表时ScrollView就会暂停滚动
scrollView.setTargetView(tradingChart)

方案二:给图表设置触摸监听(更轻量,不用自定义View)

如果不想改ScrollView的代码,直接给TradingView图表加个触摸监听,告诉ScrollView什么时候别抢事件就行。

val tradingChart = view.findViewById<View>(R.id.your_trading_view_chart)
val scrollView = view.findViewById<ScrollView>(R.id.your_scroll_view)

tradingChart.setOnTouchListener { _, event ->
    when (event.action) {
        MotionEvent.ACTION_DOWN -> {
            // 手指按下图表时,让ScrollView别拦截触摸事件
            scrollView.requestDisallowInterceptTouchEvent(true)
        }
        MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
            // 手指抬起或触摸取消时,恢复ScrollView的滚动能力
            scrollView.requestDisallowInterceptTouchEvent(false)
        }
    }
    // 返回false,让图表自己处理触摸逻辑(如果返回true,图表可能接收不到事件)
    false
}

小提醒

  • 如果你是在Fragment里用,记得在onViewCreated方法里初始化这些视图,别在onCreate里找,容易空指针。
  • 方案二里一定要返回false,不然TradingView自己的滚动逻辑会被拦截掉,还是不流畅。

我当时用方案二快速解决了问题,图表的X/Y轴滚动立刻就流畅了,亲测有效😎

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

火山引擎 最新活动