דחייה של כף היד בסטיילוס

סמל של דירוג חמישה כוכבים

עט סטיילוס יכול להיות כלי יעיל במיוחד ליצירתיות ולפרודוקטיביות. אבל כשמשתמשים מציירים, כותבים או מבצעים אינטראקציה עם אפליקציה באמצעות סטיילוס, לפעמים הם נוגעים במסך עם כף היד. אירוע המגע יכול להיות מדווח לאפליקציה לפני שהמערכת מזהה את האירוע ומבטלת אותו כמגע מקרי של כף היד.

שיטות מומלצות

האפליקציה צריכה לזהות אירועי מגע מיותרים ולהתעלם מהם. ב-Jetpack Compose, אפשר לגשת ל-Android MotionEvent הבסיסי מ-PointerEvent. בודקים את MotionEvent אם מופיע ACTION_CANCEL, שמציין שצריך להפסיק את התנועה ויכול להיות שצריך לבטל אותה. ב-Android 13 (רמת API‏ 33) ומעלה, בודקים את הדגל FLAG_CANCELED באירועים ACTION_CANCEL ו-ACTION_POINTER_UP. הדגל הזה מספק אות חזק לכך שהנגיעה הייתה לא מכוונת, למשל נגיעה עם כף היד.

אלמנטים

  • Modifier.pointerInput(): משנה ההגדרה של Compose שמשמש לעיבוד קלט של מצביע.
  • PointerEvent: מייצג אירוע של הצבעה ב-Compose, שמכיל שינוי אחד או יותר.
  • PointerEvent.motionEvent: מאפיין של התוסף שמאפשר גישה ל-Android MotionEvent הבסיסי (ניתן להגדרה כ-nullable).
  • MotionEvent: מייצג אירועי מגע ותנועה. מכיל את המידע שנדרש כדי לקבוע אם צריך להתעלם מאירוע.
  • ACTION_CANCEL: הקבוע MotionEvent מציין שתנועה בוטלה. התנועה צריכה להיפסק, ויכול להיות שיהיה צורך לבטל את הפעולה.
  • ACTION_POINTER_UP: קבוע MotionEvent שמציין שהצבעה שאינה הצבעה ראשונה הסתיימה (כלומר, לא נוצר יותר מגע עם מסך המכשיר).
  • FLAG_CANCELED: קבוע MotionEvent שמציין שהעברת מצביע למעלה גרמה לאירוע מגע לא מכוון. נוספו לאירועים ACTION_POINTER_UP ו-ACTION_CANCEL ב-Android 13 (רמת API‏ 33) ומעלה.

צעדים

בודקים את אובייקטים MotionEvent שנשלחים לאפליקציה. משתמשים בממשקי ה-API של MotionEvent כדי לקבוע את מאפייני האירוע:

  • אירועים של הצבעה יחידה – בודקים את ACTION_CANCEL, שמציין שהתנועה צריכה להיפסק. ב-Android 13 ואילך, כדאי גם לבדוק אם מופיע הסמל FLAG_CANCELED כדי לוודא שההקשה הייתה לא מכוונת.
  • אירועים של כמה מצביעים – ב-Android 13 ומעלה, בודקים את ACTION_POINTER_UP ואת FLAG_CANCELED כדי לזהות מגעים לא מכוונים.

כדי להגיב לאירועים האלה, צריך להפסיק את התנועה ולבטל את כל השינויים הזמניים.

1. קבלת אובייקטים של אירועי תנועה

אפשר להשתמש ב-Modifier.pointerInput כדי לעבד קלט של מצביע ברכיב קומפוזבילי. במסגרת היקף הקלט של מצביע, משתמשים ב-awaitPointerEventScope וב-awaitPointerEvent כדי לקבל אירועים, ומאחזרים את Android MotionEvent הבסיסי באמצעות המאפיין 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. ביטול התנועה

אחרי שמזהים מגע של כף היד, אפשר לבטל את האפקטים במסך של תנועת היד.

באפליקציה צריך לשמור היסטוריה של פעולות המשתמש, כדי שאפשר יהיה לבטל פעולות לא מכוונות כמו מגע של כף היד. דוגמה מופיעה במאמר הטמעה של אפליקציית ציור בסיסית בשיעור Codelab בנושא שיפור התמיכה בסטיילוס באפליקציית Android.

תוצאות

האפליקציה יכולה עכשיו לזהות ולדחות מגעים של כף היד באירועים של כמה מצביעים ב-Android 13 ומעלה ברמות API ובאירועים של מצביע יחיד בכל רמות ה-API.

מקורות מידע נוספים

למידע נוסף, קראו את המאמרים הבאים: