簡體   English   中英

SimpleOnGestureListener.onScroll 收到 null 值並崩潰

[英]SimpleOnGestureListener.onScroll receives a null value and crashes

我正在使用手勢檢測器從滾動視圖中捕獲滾動事件:

val gestureDetector = GestureDetector(this.fragment.activity, ScrollGestureListener(scrollView))
scrollView.setOnTouchListener(OnTouchListener { view, event ->
    gestureDetector.onTouchEvent(event)
    return@OnTouchListener false
})

internal inner class ScrollGestureListener(view: View) : GestureDetector.SimpleOnGestureListener() {
    override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
        this@DocumentViewer.onDrag()
        return true
    }
}

使用 compileSdkVersion 30 時,我的應用程序會在onScroll function 上崩潰,因為第一個參數總是收到 null 值。 我通過將第一個參數設為可選來解決這個問題:

override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {

現在我正在嘗試將我的 compileSdkVersion 更新為 33,並且上面的行將不再編譯。 但是,如果我恢復到標准的 function 簽名,那么當我滾動滾動視圖時應用程序會再次崩潰。

對此SO 帖子的評論說,“如果手勢檢測器以外的其他東西消耗 ACTION_DOWN 事件,你會遇到這樣的崩潰。” 但我無法弄清楚還有什么會這樣做。 我在這個片段的其他一些視圖上有手勢檢測器,但如果我注釋掉所有這些代碼,崩潰仍然存在。

我暫時將onDown的實現添加到我的ScrollGestureListener並且它從未被調用過,所以這似乎與 ACTION_DOWN 評論有關。

查看GestureDetector.java的源代碼,我看到它發送給onScroll的第一個參數是mCurrentDownEvent ,因此這似乎也與 ACTION_DOWN 評論有關。 但是,如果我在 Android Studio 中向GestureDetector.java添加斷點, mCurrentDownEvent永遠不會顯示為 null。此外,它始終與作為第二個參數 ( ev ) 傳遞的事件相同GestureDetector只是將mCurrentDownEvent設置為ev的副本。

看起來崩潰發生在GestureDetector調用onScroll時,因為未到達我的onScroll方法中的斷點,如果我刪除我的onScroll覆蓋,也會發生同樣的崩潰——顯然只是調用onScroll的超類實現會導致崩潰。 這是控制台中顯示的內容:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.arlomedia.bandhelper, PID: 18797
java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter e1
    at com.arlomedia.bandhelper.helpers.DocumentViewer$ScrollGestureListener.onScroll(Unknown Source:2)
    at android.view.GestureDetector.onTouchEvent(GestureDetector.java:788)
    at com.arlomedia.bandhelper.helpers.DocumentViewer.viewDocument$lambda-9(DocumentViewer.kt:1398)
    at com.arlomedia.bandhelper.helpers.DocumentViewer.$r8$lambda$kyj-4h2jNAIkIYOWSE7_HVetJAg(Unknown Source:0)
    at com.arlomedia.bandhelper.helpers.DocumentViewer$$ExternalSyntheticLambda7.onTouch(Unknown Source:6)
    at android.view.View.dispatchTouchEvent(View.java:15147)

在調用onTouchEvent之前,我已經嘗試向我的OnTouchListener添加某種檢查 - 如下所示:

if (event != null) {
    gestureDetector.onTouchEvent(event)
}

但是這里的event從來都不是 null,在查看它的屬性時,我看不到任何可以檢查以確定它是否會導致崩潰的東西。

另一個潛在的線索是,只有在調用onScroll時我的手指仍在屏幕上時,才會調用onTouchEvent 通常是這種情況,但我嘗試像這樣延遲它的調用:

val runnable = Runnable {
    gestureDetector.onTouchEvent(event)
}
App.instance.timerHandler.postDelayed(runnable, 1000)

然后,如果我執行滾動並在一秒鍾內將手指從屏幕上移開,則不會調用onScroll並且不會發生崩潰。 如果我執行滾動並將手指放在屏幕上超過一秒鍾,則會調用onScroll並發生崩潰。

我可以想象兩種解決此問題的方法:在調用OnTouchListener之前驗證我的onTouchEvent中的事件,或者找出導致GestureDetectoronScroll發送無效事件的原因。 但是我對兩者都沒有想法。 還有其他人有想法嗎?

我在新片段中一次一步地重建此功能以隔離問題。 滾動視圖環繞在TextView周圍,以使文本視圖可移動(慣性滾動),但我在該文本視圖上也有一個OnTouchListener ,因此我可以檢測捏合手勢,以調整文本大小。 顯然這是在吸收onDown事件,所以周圍的滾動視圖沒有收到它。

我假設有一種方法可以在兩個視圖之間共享onDown事件,但在我的例子中,將捏合手勢檢測器從內部文本視圖移動到外部滾動視圖更容易,因此滾動手勢檢測器和捏合手勢檢測器處於打開狀態同樣的觀點——像這樣:

val scrollGestureDetector = GestureDetector(this.fragment.activity, ScrollGestureListener(scrollView))
val pinchGestureDetector = GestureDetector(this.fragment.activity, PinchGestureListener(scrollView))
scrollView.setOnTouchListener(OnTouchListener { view, event ->
    scrollGestureDetector.onTouchEvent(event)
    pinchGestureDetector.onTouchEvent(event)
    return@OnTouchListener false
})

internal inner class ScrollGestureListener(view: View) : GestureDetector.SimpleOnGestureListener() {
    override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
        this@DocumentViewer.onDrag()
        return true
    }
}

internal inner class PinchGestureListener(view: View) : ScaleGestureDetector.SimpleOnScaleGestureListener() {
    override fun onScale(detector: ScaleGestureDetector): Boolean {
        this@DocumentViewer.onZoom()
        return true
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM