الميزات المتقدّمة لقلم الشاشة

يوفّر نظاما التشغيل Android وChromeOS مجموعة متنوعة من واجهات برمجة التطبيقات لمساعدتك في إنشاء تطبيقات توفّر للمستخدمين تجربة استثنائية لقلم الشاشة. تعرض فئة MotionEvent معلومات حول تفاعل قلم الشاشة مع الشاشة، بما في ذلك ضغط قلم الشاشة والاتجاه والإمالة والتمرير و"رصد راحة اليد". تعمل الرسومات ذات وقت الاستجابة المنخفض ومكتبات تنبؤ الحركة على تحسين العرض بقلم الشاشة على الشاشة لمنح المستخدمين تجربة طبيعية شبيهة بالقلم والورق.

MotionEvent

تمثّل الفئة MotionEvent تفاعلات المستخدمين التي يُدخلها المستخدمون، مثل موضع مؤشرات اللمس وحركة مؤشرات اللمس على الشاشة. بالنسبة إلى الإدخال بقلم الشاشة، يعرض MotionEvent أيضًا بيانات الضغط والاتجاه والإمالة والتمرير.

بيانات الأحداث

للوصول إلى بيانات MotionEvent، يمكنك إضافة معدِّل pointerInput إلى المكوّنات:

@Composable
fun Greeting() {
    Text(
        text = "Hello, Android!", textAlign = TextAlign.Center, style = TextStyle(fontSize = 5.em),
        modifier = Modifier
            .pointerInput(Unit) {
                awaitEachGesture {
                    while (true) {
                        val event = awaitPointerEvent()
                        event.changes.forEach { println(it) }
                    }
                }
            },
    )
}

يوفّر كائن MotionEvent بيانات ذات صلة بالجوانب التالية لحدث واجهة المستخدم:

  • الإجراءات: التفاعل المادي مع الجهاز - لمس الشاشة، تحريك مؤشر الماوس فوق سطح الشاشة، وتمرير مؤشر الماوس فوق سطح الشاشة
  • المؤشرات: معرّفات الكائنات التي تتفاعل مع الشاشة، مثل الإصبع وقلم الشاشة والماوس
  • المحور: نوع البيانات - الإحداثيات س و ص، الضغط، الإمالة، الاتجاه، والتمرير (المسافة)

المهام

لتنفيذ دعم قلم الشاشة، يجب أن تفهم الإجراء الذي يتخذه المستخدم.

توفّر MotionEvent مجموعة متنوعة من ثوابت ACTION التي تحدد أحداث الحركة. تشمل أهم الإجراءات المتعلقة بقلم الشاشة ما يلي:

الإجراء الوصف
ACTION_DOWN
ACTION_POINTER_DOWN
تواصل المؤشر مع الشاشة.
الإجراء_MOVE يتحرك المؤشر على الشاشة.
ACTION_UP
ACTION_POINTER_UP
لم يعُد المؤشر على اتصال بالشاشة.
إلغاء الإجراء عند الحاجة إلى إلغاء مجموعة الحركة السابقة أو الحالية.

يمكن لتطبيقك تنفيذ مهام مثل بدء ضغطة جديدة عند حدوث ACTION_DOWN، ورسم ضغط المفاتيح باستخدام ACTION_MOVE, وإنهاء الضغط عند تشغيل ACTION_UP.

تُسمى مجموعة إجراءات MotionEvent من ACTION_DOWN إلى ACTION_UP لمؤشر معيّن مجموعة الحركة.

المؤشرات

معظم الشاشات عبارة عن نقاط اتصال متعددة: يعين النظام مؤشرًا لكل إصبع أو قلم شاشة أو ماوس أو أي عنصر يشير إلى الشاشة ويتفاعل مع الشاشة. يتيح لك مؤشر المؤشر الحصول على معلومات المحور لمؤشر معيّن، مثل موضع الإصبع الأول عند لمس الشاشة أو الموضع الثاني.

تتراوح فهارس المؤشرات من صفر إلى عدد المؤشرات التي يتم عرضها عند احتساب قيمة MotionEvent#pointerCount() مطروحًا منها 1.

يمكن الوصول إلى قيم المحور للمؤشرات باستخدام الطريقة getAxisValue(axis, pointerIndex). عند إسقاط فهرس المؤشر، يعرض النظام قيمة المؤشر الأول، المؤشر صفر (0).

تحتوي MotionEvent عناصر على معلومات عن نوع المؤشر المستخدَم. يمكنك الحصول على نوع المؤشر من خلال التكرار باستخدام فهارس المؤشر واستدعاء الطريقة getToolType(pointerIndex).

لمزيد من المعلومات حول المؤشرات، اطّلِع على التعامل مع إيماءات اللمس المتعدد.

إدخالات قلم الشاشة

يمكنك الفلترة بحثًا عن إدخالات قلم الشاشة باستخدام TOOL_TYPE_STYLUS:

val isStylus = TOOL_TYPE_STYLUS == event.getToolType(pointerIndex)

يمكن لقلم الشاشة أيضًا الإبلاغ عن استخدامه كممحاة من خلال TOOL_TYPE_ERASER:

val isEraser = TOOL_TYPE_ERASER == event.getToolType(pointerIndex)

بيانات محور قلم الشاشة

يوفّر كل من ACTION_DOWN وACTION_MOVE بيانات محور حول قلم الشاشة، أي الإحداثيتَين x وy، والضغط والاتجاه والإمالة والتمرير.

لإتاحة الوصول إلى هذه البيانات، توفّر واجهة برمجة التطبيقات MotionEvent واجهة برمجة التطبيقات getAxisValue(int)، حيث تكون المَعلمة أي من معرّفات المحاور التالية:

Axis القيمة المعروضة getAxisValue()
AXIS_X الإحداثي السيني (X) لحدث حركة.
AXIS_Y الإحداثي الصادي (Y) لحدث حركة.
AXIS_PRESSURE بالنسبة إلى الشاشة التي تعمل باللمس أو لوحة اللمس، يتم تطبيق الضغط بإصبع أو قلم شاشة أو مؤشر آخر. بالنسبة للماوس أو كرة التعقب، 1 في حالة الضغط على الزر الأساسي، 0 في الحالات الأخرى.
AXIS_ORIENTATION بالنسبة إلى الشاشة التي تعمل باللمس أو لوحة اللمس، اتجاه الإصبع أو قلم الشاشة أو أي مؤشر آخر بالنسبة إلى المستوى العمودي للجهاز
AXIS_TILT زاوية إمالة قلم الشاشة بوحدات الراديان.
AXIS_DISTANCE مسافة قلم الشاشة عن الشاشة

على سبيل المثال، تعرض MotionEvent.getAxisValue(AXIS_X) الإحداثي x للمؤشر الأول.

يُرجى الاطّلاع أيضًا على التعامل مع إيماءات اللمس المتعدد.

الموضع

يمكنك استرداد إحداثيي x وy لمؤشر باستخدام الاستدعاءات التالية:

قلم الشاشة الذي يرسم على الشاشة مع تحديد الإحداثيتين x وy
الشكل 1. إحداثيات الشاشة "س" و"ص" لمؤشر قلم الشاشة.

الضغط

يمكنك استرداد ضغط المؤشر باستخدام MotionEvent#getAxisValue(AXIS_PRESSURE) أو بالنسبة إلى المؤشر الأول، MotionEvent#getPressure().

تتراوح قيمة الضغط للشاشات التي تعمل باللمس أو لوحات اللمس بين 0 (بدون ضغط) و1، ولكن يمكن عرض قيم أعلى بناءً على معايرة الشاشة.

خط قلم الشاشة الذي يمثل سلسلة مستمرة من الضغط المنخفض إلى المرتفع. درجة السُمك ضيقة و باهتة على اليسار، مما يشير إلى الضغط المنخفض. يصبح الخط أوسع وأغمق من اليسار إلى اليمين حتى يصبح أوسع وأغمق في أقصى اليمين، مما يشير إلى أعلى ضغط.
الشكل 2. تمثيل الضغط: ضغط منخفض على اليسار، ضغط مرتفع على اليمين.

الاتجاه

يشير الاتجاه إلى الاتجاه الذي يشير إليه قلم الشاشة.

يمكن استرداد اتجاه المؤشر باستخدام getAxisValue(AXIS_ORIENTATION) أو getOrientation() (للمؤشر الأول).

بالنسبة لقلم الشاشة، يتم عرض الاتجاه كقيمة راديان تتراوح بين 0 وباي (باي) في اتجاه عقارب الساعة أو من 0 إلى باي باي عكس عقارب الساعة.

يتيح لك التوجيه استخدام فرشاة حقيقية. على سبيل المثال، إذا كان قلم الشاشة يمثّل فرشاة مسطحة، يعتمد عرض الفرشاة المسطحة على اتجاه قلم الشاشة.

الشكل 3. قلم شاشة يشير إلى اليسار حوالي 0 .57 وحدة راديان.

إمالة

تقيس الإمالة ميل قلم الشاشة بالنسبة إلى الشاشة.

تعرض الإمالة الزاوية الموجبة لقلم الشاشة بوحدات الراديان، حيث يكون الصفر متعامدًا مع الشاشة ويكون باي/2 مسطحًا على السطح.

يمكن استرداد زاوية الإمالة باستخدام getAxisValue(AXIS_TILT) (ما مِن اختصار للمؤشر الأول).

يمكن استخدام الإمالة لإعادة إنتاج العناصر القريبة قدر الإمكان من الأدوات الواقعية، مثل محاكاة التظليل بقلم رصاص مائل.

يميل قلم الشاشة إلى سطح الشاشة بمقدار 40 درجة تقريبًا.
الشكل 4. تمت إمالة قلم الشاشة بمقدار 0 .785 وحدة راديان، أو 45 درجة من العمودي.

تمرير مؤشر الماوس

يمكن معرفة مسافة قلم الشاشة من الشاشة باستخدام getAxisValue(AXIS_DISTANCE). ترجع الطريقة قيمة من 0.0 (الاتصال بالشاشة) إلى قيم أعلى كلما تحرك قلم الشاشة بعيدًا عن الشاشة. تعتمد مسافة التمرير بين الشاشة وطرف (النقطة) لقلم الشاشة على الشركة المصنعة للشاشة وقلم الشاشة. وبما أنّ عمليات التنفيذ قد تتفاوت فلا تعتمد على قيم دقيقة للوظائف الأساسية للتطبيق

يمكن استخدام التمرير فوق قلم الشاشة لمعاينة حجم الفرشاة أو الإشارة إلى أنّه سيتم اختيار زر.

الشكل 5. قلم شاشة يمر فوق شاشة. يتفاعل التطبيق مع أنّ قلم الشاشة لا يلمس سطح الشاشة.

ملاحظة: توفر ميزة Compose مُعدِّلات تؤثر في الحالة التفاعلية لعناصر واجهة المستخدم:

  • hoverable: اضبط المكوِّن ليكون قابلاً للتمرير باستخدام أحداث الدخول والخروج من خلال المؤشر.
  • indication: يرسم التأثيرات المرئية لهذا المكوِّن عند حدوث تفاعلات.

رفض راحة اليد والتنقّل والإدخالات غير المرغوب فيها

في بعض الأحيان، يمكن لشاشات اللمس المتعددة أن تسجّل اللمسات غير المرغوب فيها، مثلاً عندما يضع المستخدم يده على الشاشة بشكل طبيعي للحصول على دعم أثناء الكتابة بخط اليد. وتجدر الإشارة إلى أنّ "رفض راحة اليد" هي آلية ترصد هذا السلوك وتُعلِمك بضرورة إلغاء مجموعة "MotionEvent" الأخيرة.

ونتيجة لذلك، يجب الاحتفاظ بسجلّ من البيانات التي أدخلها المستخدم كي تتم إزالة اللمسات غير المرغوب فيها من الشاشة وعرض البيانات التي أدخلها المستخدم بشكل صحيح.

ACTION_CANCEL وFLAG_CANCELED

تم تصميم كل من ACTION_CANCEL وFLAG_CANCELED لإخبارك بأنّه يجب إلغاء مجموعة MotionEvent السابقة من آخر مجموعة (ACTION_DOWN)، وبالتالي يمكنك، على سبيل المثال، التراجع عن الضغط الأخير على تطبيق رسم لمؤشر معيّن.

إلغاء الإجراء

تمت الإضافة في الإصدار 1.0 من نظام التشغيل Android (المستوى 1 من واجهة برمجة التطبيقات)

يشير الرمز ACTION_CANCEL إلى أنّه يجب إلغاء المجموعة السابقة من أحداث الحركة.

يتم تشغيل ACTION_CANCEL عند رصد أيٍّ مما يلي:

  • إيماءات التنقل
  • راحة اليد

عند تشغيل ACTION_CANCEL، عليك تحديد المؤشر النشط باستخدام getPointerId(getActionIndex()). بعد ذلك، أزِل الحد الخارجي الذي تم إنشاؤه باستخدام هذا المؤشر من سجلّ الإدخال وأعِد عرض المشهد.

تم إلغاء الإشارة

تمت الإضافة في Android 13 (المستوى 33)

يشير FLAG_CANCELED إلى أنّ المؤشر للأعلى كان لمسة غير مقصودة للمستخدم. يتم ضبط العلامة عادةً عندما يلمس المستخدم الشاشة عن طريق الخطأ، مثل الإمساك بالجهاز أو وضع راحة يده على الشاشة.

يمكنك الوصول إلى قيمة العلامة على النحو التالي:

val cancel = (event.flags and FLAG_CANCELED) == FLAG_CANCELED

إذا تم ضبط العلامة، عليك التراجع عن آخر مجموعة MotionEvent من آخر مجموعة ACTION_DOWN من هذا المؤشر.

مثل ACTION_CANCEL، يمكن العثور على المؤشر في getPointerId(actionIndex).

الشكل 6. يؤدي خط قلم الشاشة ولمس راحة اليد إلى إنشاء MotionEvent مجموعة. تم إلغاء ميزة "لمس راحة اليد" وتتم إعادة عرض الشاشة.

إيماءات ملء الشاشة، ومن الحافة إلى الحافة، وإيماءات التنقّل

إذا كان التطبيق في وضع ملء الشاشة ويحتوي على عناصر قابلة للتنفيذ بالقرب من الحافة، مثل لوحة الرسم أو تطبيق تدوين الملاحظات، فقد يؤدي التمرير سريعًا من أسفل الشاشة لعرض شريط التنقل أو نقل التطبيق إلى الخلفية إلى لمس لوحة غير مرغوب فيها.

الشكل 7. يمكنك التمرير سريعًا لنقل تطبيق إلى الخلفية.

لمنع الإيماءات من تشغيل اللمسات غير المرغوب فيها في تطبيقك، يمكنك الاستفادة من المجموعات وACTION_CANCEL.

يمكنك أيضًا الاطّلاع على قسم رفض راحة اليد والتنقّل والإدخالات غير المرغوب فيها.

يمكنك استخدام طريقة setSystemBarsBehavior() وBEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE WindowInsetsController لمنع إيماءات التنقّل من التسبّب في أحداث لمس غير مرغوب فيها:

// Configure the behavior of the hidden system bars.
windowInsetsController.systemBarsBehavior =
    WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE

لمزيد من المعلومات حول إدارة الأجزاء الداخلية والإيماءات، اطّلِع على:

وقت استجابة سريع

إنّ وقت الاستجابة هو الوقت الذي تحتاجه الأجهزة والنظام والتطبيق لمعالجة البيانات التي يُدخلها المستخدم وعرضها.

وقت الاستجابة = معالجة إدخال الأجهزة ونظام التشغيل + معالجة التطبيقات + تركيب النظام

  • عرض الأجهزة
يؤدي وقت الاستجابة إلى تأخر السكتة الدماغية المعروضة عن موضع قلم الشاشة. تمثل الفجوة بين الحد الخارجي وموضع قلم الشاشة وقت الاستجابة.
الشكل 8. يؤدي وقت الاستجابة إلى تأخر السكتة الدماغية المعروضة عن موضع قلم الشاشة.

مصدر وقت الاستجابة

  • تسجيل قلم الشاشة باستخدام شاشة تعمل باللمس (الأجهزة): اتصال لاسلكي مبدئي عندما يتصل قلم الشاشة ونظام التشغيل ليتم التسجيل والمزامنة.
  • معدل أخذ العينات باللمس (الأجهزة): عدد المرات في الثانية التي تتحقّق فيها شاشة تعمل باللمس مما إذا كان المؤشر يلمس السطح، ويتراوح من 60 إلى 1000 هرتز.
  • معالجة الإدخالات (في التطبيقات): تطبيق الألوان والتأثيرات الرسومية والتحويل على البيانات التي يدخلها المستخدم.
  • عرض الرسومات (نظام التشغيل + الأجهزة): تبديل التخزين المؤقت، ومعالجة الأجهزة

رسومات ذات وقت استجابة سريع

تقلّل مكتبة رسومات Jetpack ذات وقت الاستجابة المنخفض وقت المعالجة بين البيانات التي يُدخلها المستخدم والعرض على الشاشة.

تقلل المكتبة من وقت المعالجة من خلال تجنب العرض متعدد المخزن المؤقت والاستفادة من أسلوب عرض المخزن المؤقت الأمامي، ما يعني الكتابة مباشرةً على الشاشة.

عرض المخزن المؤقت

المخزن المؤقت الأمامي هو الذاكرة التي تستخدمها الشاشة للعرض. إنه أقرب التطبيقات التي يمكن أن تتمكن من الرسم مباشرة على الشاشة. تمكن مكتبة وقت الاستجابة المنخفض التطبيقات من العرض مباشرة إلى المخزن المؤقت الأمامي. ويؤدي ذلك إلى تحسين الأداء من خلال منع تبديل المخزن المؤقت، والذي قد يحدث عند العرض المنتظم بذاكرة تخزين مؤقت متعددة أو العرض المخزّن مؤقتًا مرتين (الحالة الأكثر شيوعًا).

يكتب التطبيق إلى المخزن المؤقت للشاشة ويقرأ من المخزن المؤقت للشاشة.
الشكل 9. عرض المخزن المؤقت الأمامي
ينتقل التطبيق إلى المخزن المؤقت المتعدد، والذي يتم تبديله مع المخزن المؤقت للشاشة. يقرأ التطبيق من المخزن المؤقت للشاشة.
الشكل 10. عرض متعدد المخزن المؤقت

بالرغم من أنّ العرض المخزَّن أمام المخزن المؤقت وسيلة رائعة لعرض مساحة صغيرة من الشاشة، إلا أنّه غير مصمم سعيًا لتحديث الشاشة بأكملها. باستخدام عرض المخزن المؤقت الأمامي، يعرض التطبيق المحتوى في المخزن المؤقت الذي تتم قراءة الشاشة منه. ونتيجةً لذلك، هناك احتمال عرض أدوات أو تمزيق (انظر أدناه).

تتوفّر مكتبة وقت الاستجابة السريع من نظام التشغيل Android 10 (المستوى 29 لواجهة برمجة التطبيقات) والإصدارات الأحدث وعلى أجهزة ChromeOS التي تعمل بالإصدار Android 10 (المستوى 29 من واجهة برمجة التطبيقات) والإصدارات الأحدث.

التبعيات

توفر مكتبة وقت الاستجابة السريع مكونات تنفيذ عرض المخزن المؤقت الأمامي. تتم إضافة المكتبة كملحق في ملف build.gradle الخاص بوحدة التطبيق:

dependencies {
    implementation "androidx.graphics:graphics-core:1.0.0-alpha03"
}

استدعاءات GLFrontBufferRenderer

تتضمن مكتبة وقت الاستجابة السريع واجهة GLFrontBufferRenderer.Callback التي تحدّد الطرق التالية:

لا تأخذ مكتبة وقت الاستجابة السريع رأيًا في نوع البيانات التي تستخدمها مع GLFrontBufferRenderer.

ومع ذلك، تعالج المكتبة البيانات على أنّها مصدر لمئات من نقاط البيانات، وبالتالي يجب تصميم بياناتك لتحسين استخدام الذاكرة وتخصيصها.

طلبات معاودة الاتصال

لتفعيل عرض استدعاءات العرض، نفِّذ GLFrontBufferedRenderer.Callback وتجاوز onDrawFrontBufferedLayer() وonDrawDoubleBufferedLayer(). يستخدم GLFrontBufferedRenderer عمليات الاستدعاء لعرض بياناتك بأفضل طريقة ممكنة.

val callback = object: GLFrontBufferedRenderer.Callback<DATA_TYPE> {
   override fun onDrawFrontBufferedLayer(
       eglManager: EGLManager,
       bufferInfo: BufferInfo,
       transform: FloatArray,
       param: DATA_TYPE
   ) {
       // OpenGL for front buffer, short, affecting small area of the screen.
   }
   override fun onDrawMultiDoubleBufferedLayer(
       eglManager: EGLManager,
       bufferInfo: BufferInfo,
       transform: FloatArray,
       params: Collection<DATA_TYPE>
   ) {
       // OpenGL full scene rendering.
   }
}
تعريف نسخة افتراضية من GLFrontBufferedRenderer

يمكنك إعداد "GLFrontBufferedRenderer" من خلال تقديم "SurfaceView" وعمليات معاودة الاتصال التي أنشأتها سابقًا. يحسّن GLFrontBufferedRenderer العرض على المقدمة والتخزين المؤقت المزدوج باستخدام عمليات الاستدعاء:

var glFrontBufferRenderer = GLFrontBufferedRenderer<DATA_TYPE>(surfaceView, callbacks)
العرض

يبدأ عرض المخزن المؤقت الأمامي عند استدعاء الطريقة renderFrontBufferedLayer()، التي تؤدي إلى تشغيل استدعاء onDrawFrontBufferedLayer().

يتم استئناف العرض في ذاكرة التخزين المؤقت المزدوجة عند استدعاء الدالة commit()، والتي تؤدي إلى تشغيل استدعاء onDrawMultiDoubleBufferedLayer().

وفي المثال التالي، تنتقل العملية إلى المخزن المؤقت الأمامي (العرض السريع) عندما يبدأ المستخدم في الرسم على الشاشة (ACTION_DOWN) ويحرك المؤشر حولها (ACTION_MOVE). وتنتقل العملية إلى المخزن المؤقت المزدوج عندما يغادر المؤشر سطح الشاشة (ACTION_UP).

يمكنك استخدام requestUnbufferedDispatch() للطلب من نظام الإدخال عدم تجميع أحداث الحركة، ولكن بدلاً من ذلك يتم إرسالها عند توفّرها:

when (motionEvent.action) {
   MotionEvent.ACTION_DOWN -> {
       // Deliver input events as soon as they arrive.
       view.requestUnbufferedDispatch(motionEvent)
       // Pointer is in contact with the screen.
       glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE)
   }
   MotionEvent.ACTION_MOVE -> {
       // Pointer is moving.
       glFrontBufferRenderer.renderFrontBufferedLayer(DATA_TYPE)
   }
   MotionEvent.ACTION_UP -> {
       // Pointer is not in contact in the screen.
       glFrontBufferRenderer.commit()
   }
   MotionEvent.CANCEL -> {
       // Cancel front buffer; remove last motion set from the screen.
       glFrontBufferRenderer.cancel()
   }
}

عرض الإجراءات المطلوبة وغير المسموح بها

الإجراءات التي يُنصح بها

أجزاء صغيرة من الشاشة: الكتابة بخط اليد والرسم والرسم

الإجراءات غير المُوصى بها

تحديث بملء الشاشة، العرض الشامل، والتكبير/التصغير. يمكن أن يؤدي إلى تمزيق.

تمزيق

يحدث التمزق عندما يتم تحديث الشاشة بينما يتم تعديل المخزن المؤقت للشاشة في الوقت نفسه. يعرض جزء من الشاشة البيانات الجديدة، بينما يعرض جزء آخر البيانات القديمة.

تتم محاذاة الأجزاء العلوية والسفلية من صورة Android بشكل غير صحيح بسبب حدوث تمزيق عند تحديث الشاشة.
الشكل 11. تمزيق أثناء تحديث الشاشة من أعلى إلى أسفل.

توقُّع الحركة

تعمل مكتبة توقّع حركة Jetpack على تقليل وقت الاستجابة الذي يتم إدراكه من خلال تقدير مسار السُمك للمستخدم وتوفير نقاط مؤقتة ومصطنعة لبرنامج العرض.

تحصل مكتبة توقّعات الحركة على إدخالات حقيقية من المستخدمين ككائنات MotionEvent. تحتوي الأجسام على معلومات حول الإحداثيتَين x وy والضغط والوقت، والتي تستفيد منها أداة مؤشّر الحركة لتوقّع كائنات MotionEvent المستقبلية.

العناصر المتوقّعة البالغ عددها MotionEvent هي مجرد تقديرات. يمكن للأحداث المتوقّعة أن تقلل من وقت الاستجابة الملحوظ، ولكن يجب استبدال البيانات المتوقّعة ببيانات MotionEvent الفعلية بعد استلامها.

تتوفّر مكتبة توقّعات الحركة من نظام التشغيل Android 4.4 (المستوى 19 لواجهة برمجة التطبيقات) والإصدارات الأحدث وعلى أجهزة ChromeOS التي تعمل بالإصدار Android 9 (المستوى 28 من واجهة برمجة التطبيقات) والإصدارات الأحدث.

يؤدي وقت الاستجابة إلى تأخر السكتة الدماغية المعروضة عن موضع قلم الشاشة. يتم ملء الفجوة بين الحد الخارجي وقلم الشاشة بنقاط التنبؤ. الفجوة المتبقية هي وقت الاستجابة الذي تم رصده.
الشكل 12. تم تقليل وقت الاستجابة من خلال تنبؤ الحركة.

التبعيات

توفر مكتبة تنبؤات الحركة تنفيذ التنبؤ. تتم إضافة المكتبة كملحق في ملف build.gradle الخاص بوحدة التطبيق:

dependencies {
    implementation "androidx.input:input-motionprediction:1.0.0-beta01"
}

التنفيذ

تتضمن مكتبة توقّعات الحركة واجهة MotionEventPredictor التي تحدّد الطرق التالية:

  • record(): تخزين عناصر MotionEvent كسجلّ لإجراءات المستخدم
  • predict(): عرض MotionEvent متوقّع
تعريف المثيل MotionEventPredictor
var motionEventPredictor = MotionEventPredictor.newInstance(view)
تزويد المتنبئ بالبيانات
motionEventPredictor.record(motionEvent)
التنبؤ

when (motionEvent.action) {
   MotionEvent.ACTION_MOVE -> {
       val predictedMotionEvent = motionEventPredictor?.predict()
       if(predictedMotionEvent != null) {
            // use predicted MotionEvent to inject a new artificial point
       }
   }
}

الإجراءات المحبّذة وغير المحبّذة في توقُّع الحركة

الإجراءات التي يُنصح بها

إزالة نقاط التوقّع عند إضافة نقطة متوقَّعة جديدة

الإجراءات غير المُوصى بها

ولا تستخدِم نقاط التوقّع للعرض النهائي.

تطبيقات تدوين الملاحظات

يسمح نظام التشغيل ChromeOS لتطبيقك بتعريف بعض إجراءات تدوين الملاحظات.

لتسجيل تطبيق كتطبيق لتدوين الملاحظات على ChromeOS، يُرجى الاطّلاع على توافق الإدخال.

لتسجيل تطبيق كتدوين ملاحظات على Android، يُرجى الاطّلاع على إنشاء تطبيق تدوين ملاحظات.

في Android 14 (المستوى 34)، تم تقديم هدف ACTION_CREATE_NOTE الذي يتيح لتطبيقك بدء نشاط لتدوين الملاحظات على شاشة القفل.

التعرّف على الحبر الرقمي باستخدام مجموعة أدوات تعلُّم الآلة

من خلال التعرّف على الحبر الرقمي من مجموعة أدوات تعلُّم الآلة، يمكن لتطبيقك التعرّف على النص المكتوب بخط اليد على سطح رقمي بمئات من اللغات. يمكنك أيضًا تصنيف الرسومات.

توفّر حزمة تعلّم الآلة فئة Ink.Stroke.Builder لإنشاء عناصر Ink يمكن معالجتها من خلال نماذج تعلُّم الآلة لتحويل الكتابة بخط اليد إلى نص.

بالإضافة إلى ميزة التعرُّف على الكتابة بخط اليد، يمكن للنموذج التعرّف على الإيماءات، مثل الحذف والدائرة.

يمكنك الاطّلاع على التعرف على الحبر الرقمي لمعرفة المزيد من المعلومات.

مصادر إضافية

أدلة المطوِّرين

الدروس التطبيقية حول الترميز