防止誤觸觸控筆

五星評等圖示

觸控筆是特別能協助使用者提高工作效率和激發創意的工具。不過,當他們使用觸控筆繪圖、書寫或與應用程式互動時,有時手掌會碰到螢幕。在系統將這類事件辨別為手掌誤觸,並加以忽略之前,可能就會先將觸控事件回報給您的應用程式。

最佳做法

您的應用程式必須辨識並忽略不必要的觸控事件。在 Jetpack Compose 中,您可以從 PointerEvent 存取基礎 Android MotionEvent。檢查 MotionEventACTION_CANCEL,這表示手勢應停止,可能需要回溯。在 Android 13 (API 級別 33) 以上版本中,請檢查 ACTION_CANCELACTION_POINTER_UP 事件的 FLAG_CANCELED 旗標,這項旗標會提供強烈信號,指出觸控是無意間發生,例如手掌觸控。

要件

  • Modifier.pointerInput():用於處理指標輸入內容的 Compose 修飾符。
  • PointerEvent:代表 Compose 中的指標事件,其中包含一或多項變更。
  • PointerEvent.motionEvent:擴充功能屬性,可存取基礎 Android MotionEvent (可為空值)。
  • MotionEvent:代表觸控和動作事件,包含判斷是否應忽略事件所需的資訊。
  • ACTION_CANCELMotionEvent 常數,表示手勢已取消,手勢應停止,且可能需要回溯。
  • ACTION_POINTER_UPMotionEvent 常數,表示第一個指標以外的指標已上移 (也就是已放棄與裝置螢幕接觸)。
  • FLAG_CANCELEDMotionEvent 常數,表示指標上移是無意間的觸控事件所致。已在 Android 13 (API 級別 33) 以上版本加入 ACTION_POINTER_UPACTION_CANCEL 事件中。

步驟

檢查調度給應用程式的 MotionEvent 物件。請使用 MotionEvent API 判斷事件特性:

  • 單指標事件 - 檢查 ACTION_CANCEL,這表示手勢應停止。如果是 Android 13 以上版本,請一併檢查 FLAG_CANCELED,確認是否為誤觸。
  • 多指標事件 - 在 Android 13 以上版本中,檢查 ACTION_POINTER_UPFLAG_CANCELED,找出無意間的觸控操作。

請停止手勢並還原所有暫時變更,以回應這些事件。

1. 取得動作事件物件

使用 Modifier.pointerInput 處理可組合函式上的指標輸入內容。在指標輸入範圍內,使用 awaitPointerEventScopeawaitPointerEvent 接收事件,並使用 motionEvent 屬性擷取基礎 Android MotionEvent

import androidx.compose.ui.input.pointer.pointerInput
    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                awaitPointerEventScope {
                    while (true) {
                        val event = awaitPointerEvent()
                        val motionEvent = event.motionEvent
                        if (motionEvent != null) {
                            // Process motion event.
                        }
                    }
                }
            }
    )

2. 判斷事件動作和標記

檢查 MotionEvent 是否有 ACTION_CANCEL,這表示所有 API 級別上的單指標事件。如果是 Android 13 以上版本,請檢查 ACTION_POINTER_UP 是否有 FLAG_CANCELED

import androidx.compose.ui.input.pointer.pointerInput
    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                awaitPointerEventScope {
                    while (true) {
                        val event = awaitPointerEvent()
                        val motionEvent = event.motionEvent ?: continue

                        when (motionEvent.actionMasked) {
                            MotionEvent.ACTION_CANCEL -> {
                                // Process canceled single-pointer motion event for all SDK versions.
                            }
                            MotionEvent.ACTION_POINTER_UP -> {
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
                                    (motionEvent.flags and MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED
                                ) {
                                    // Process canceled multi-pointer motion event for Android 13 and higher.
                                }
                            }
                        }
                    }
                }
            }
    )

3. 取消手勢

辨識出手掌觸碰事件後,您可以取消手勢在螢幕上引發的操作。

您的應用程式必須保留使用者動作記錄,以便在有手掌觸碰這類情形發生時,取消這些無意的輸入操作。如需範例,請參閱「強化 Android 應用程式中的觸控筆支援」程式碼研究室中的「實作基本繪圖應用程式」。

結果

您的應用程式現在可以辨別並拒絕多指標事件 (在 Android 13 以上的 API 級別上) 和單指標事件 (在所有 API 級別上) 的手掌觸碰操作了。

其他資源

如需更多資訊,請參考下列資源: