การปฏิเสธฝ่ามือที่ใช้สไตลัส

ไอคอนให้คะแนน 5 ดาว

สไตลัสเป็นเครื่องมือที่ช่วยให้ทำงานได้อย่างมีประสิทธิภาพและสร้างสรรค์เป็นพิเศษ แต่เมื่อผู้ใช้ วาด เขียน หรือโต้ตอบกับแอปโดยใช้สไตลัส บางครั้งผู้ใช้อาจสัมผัส หน้าจอด้วยฝ่ามือ ระบบจะรายงานเหตุการณ์การแตะไปยังแอปของคุณ ก่อนที่ระบบจะจดจำและปิดเหตุการณ์ดังกล่าวว่าเป็นการแตะด้วยฝ่ามือโดยไม่ตั้งใจ

แนวทางปฏิบัติแนะนำ

แอปต้องระบุเหตุการณ์สัมผัสที่ไม่เกี่ยวข้องและไม่สนใจเหตุการณ์เหล่านั้น ใน Jetpack Compose คุณสามารถเข้าถึง MotionEvent ของ Android ที่อยู่เบื้องหลังได้จาก PointerEvent ตรวจสอบ MotionEvent สำหรับ ACTION_CANCEL ซึ่ง บ่งบอกว่าควรหยุดท่าทางสัมผัสและอาจต้องย้อนกลับ ใน Android 13 (API ระดับ 33) ขึ้นไป ให้ตรวจสอบค่าสถานะ FLAG_CANCELED ในเหตุการณ์ ACTION_CANCEL และ ACTION_POINTER_UP ซึ่งให้ สัญญาณที่ชัดเจนว่าการแตะนั้นไม่ได้ตั้งใจ เช่น การแตะด้วยฝ่ามือ

ส่วนผสม

  • Modifier.pointerInput(): ตัวแก้ไข Compose ที่ใช้ในการประมวลผลอินพุตของเคอร์เซอร์
  • PointerEvent: แสดงเหตุการณ์เคอร์เซอร์ใน Compose ซึ่งมีการเปลี่ยนแปลงอย่างน้อย 1 รายการ
  • PointerEvent.motionEvent: พร็อพเพอร์ตี้ส่วนขยายที่ให้สิทธิ์เข้าถึง MotionEvent ของ Android ที่อยู่เบื้องหลัง (อาจเป็นค่าว่าง)
  • MotionEvent: แสดงเหตุการณ์การสัมผัสและการเคลื่อนไหว มี ข้อมูลที่จำเป็นต่อการพิจารณาว่าควรละเว้นเหตุการณ์หรือไม่
  • ACTION_CANCEL: ค่าคงที่ MotionEvent ที่ระบุว่ามีการยกเลิกท่าทางสัมผัส ท่าทางสัมผัสควรหยุดและอาจต้องย้อนกลับ
  • ACTION_POINTER_UP: ค่าคงที่ MotionEvent ที่ระบุว่าพอยน์เตอร์ อื่นที่ไม่ใช่พอยน์เตอร์แรกได้เลิกสัมผัสแล้ว (กล่าวคือ ไม่ได้สัมผัส หน้าจออุปกรณ์แล้ว)
  • FLAG_CANCELED: MotionEvent ค่าคงที่ที่ระบุว่าการเลื่อนตัวชี้ขึ้นทำให้เกิดเหตุการณ์สัมผัสโดยไม่ตั้งใจ เพิ่มลงในเหตุการณ์ ACTION_POINTER_UP และ ACTION_CANCEL ใน Android 13 (API ระดับ 33) ขึ้นไป

ขั้นตอน

ตรวจสอบออบเจ็กต์ MotionEvent ที่ส่งไปยังแอป ใช้ MotionEvent API เพื่อระบุลักษณะของเหตุการณ์

  • เหตุการณ์แบบแตะครั้งเดียว - ตรวจสอบ ACTION_CANCEL ซึ่งระบุว่า ควรหยุดท่าทางสัมผัส ใน Android 13 ขึ้นไป ให้มองหา FLAG_CANCELED เพื่อยืนยันว่าการแตะนั้นไม่ได้ตั้งใจ
  • เหตุการณ์แบบหลายนิ้ว - ใน Android 13 ขึ้นไป ให้ตรวจสอบ ACTION_POINTER_UP และ FLAG_CANCELED เพื่อระบุการแตะโดยไม่ตั้งใจ

ตอบสนองต่อเหตุการณ์เหล่านี้โดยหยุดท่าทางสัมผัสและย้อนกลับการเปลี่ยนแปลงชั่วคราว

เป็นการแตะโดยตั้งใจหรือไม่

1. รับออบเจ็กต์เหตุการณ์การเคลื่อนไหว

ใช้ Modifier.pointerInput เพื่อประมวลผลอินพุตของเคอร์เซอร์ใน Composable ภายในขอบเขตอินพุตของเคอร์เซอร์ ให้ใช้ awaitPointerEventScope และ awaitPointerEvent เพื่อ รับเหตุการณ์ และดึงข้อมูล 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. กำหนดการดำเนินการและ Flag ของเหตุการณ์

ตรวจสอบ 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. เลิกทำท่าทางสัมผัส

เมื่อระบุการสัมผัสด้วยฝ่ามือได้แล้ว คุณจะยกเลิกเอฟเฟกต์บนหน้าจอของท่าทางสัมผัสได้

แอปของคุณต้องเก็บประวัติการดำเนินการของผู้ใช้ไว้เพื่อให้ยกเลิกอินพุตที่ไม่ตั้งใจได้ เช่น การสัมผัสด้วยฝ่ามือ ดูตัวอย่างได้ที่ Implement a basic drawing app ใน Codelab Enhance stylus support in an Android app

ผลลัพธ์

ตอนนี้แอปของคุณสามารถระบุและปฏิเสธการสัมผัสด้วยฝ่ามือสำหรับเหตุการณ์แบบหลายตัวชี้ใน Android 13 และ API ระดับที่สูงกว่า รวมถึงเหตุการณ์แบบตัวชี้เดียวใน API ทุกระดับได้แล้ว

แหล่งข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมได้ที่หัวข้อต่อไปนี้