على أجهزة ChromeOS، يتفاعل العديد من المستخدمين مع التطبيقات باستخدام لوحة المفاتيح أو الماوس أو لوحة التتبّع أو قلم الشاشة أو عصا التحكّم. على الرغم من أنّ أجهزة الإدخال هذه تُستخدم أيضًا على هواتف Android، إلا أنّها ليست شائعة ويغفل عنها المطوّرون غالبًا.
على المطوّرين الذين يريدون أن يعمل تطبيقهم بشكل جيد مع الإدخال على ChromeOS والأجهزة الأخرى التي تتوافق مع Android وتتضمّن شاشة كبيرة، الاطّلاع على التحسينات التالية:
- أضِف ميزة إتاحة استخدام لوحة المفاتيح الأساسية واختبِرها، مثل التنقّل باستخدام الأسهم ومفاتيح التبويب، ومفتاح Enter لتأكيد إدخال النص، ومفتاح المسافة لتشغيل المحتوى في تطبيقات الوسائط وإيقافه مؤقتًا.
-
أضِف اختصارات لوحة المفاتيح العادية حيثما ينطبق ذلك، مثل
ctrl+zللتراجع، وctrl+sللحفظ. - اختبِر التفاعلات الأساسية مع الماوس، مثل النقر بزر الماوس الأيمن لعرض قائمة السياق، وتغيير الرموز عند التمرير فوقها، وأحداث التمرير باستخدام عجلة الماوس أو لوحة اللمس في طرق العرض المخصّصة.
- اختبِر أجهزة الإدخال الخاصة بالتطبيقات، مثل القلم الرقمي لتطبيقات الرسم، ووحدات التحكّم في الألعاب، ووحدات التحكّم في واجهة الآلات الموسيقية الرقمية (MIDI) لتطبيقات الموسيقى.
- ننصحك بتوفير إمكانات متقدّمة لإدخال البيانات يمكن أن تميّز التطبيق في بيئات أجهزة الكمبيوتر المكتبي، مثل لوحة اللمس كأداة لتخفيف الصوت تدريجيًا في تطبيقات DJ، وإمكانية استخدام الماوس في الألعاب، واختصارات لوحة المفاتيح الموسّعة للمستخدمين المتقدّمين.
لوحة المفاتيح
تساهم طريقة استجابة تطبيقك لإدخال لوحة المفاتيح في تقديم تجربة جيدة على الكمبيوتر. هناك ثلاثة أنواع من إدخال لوحة المفاتيح: التنقّل وضغطات المفاتيح والاختصارات.
التنقل
لا يتم عادةً توفير إمكانية التنقّل باستخدام لوحة المفاتيح في التطبيقات التي تركّز على اللمس، ولكن يتوقّع المستخدمون توفّرها عند استخدام تطبيق مع لوحة مفاتيح. ويمكن أن يكون هذا الإعداد ضروريًا أيضًا للمستخدمين الذين لديهم احتياجات متعلّقة بسهولة الاستخدام على كل من الهواتف وأجهزة الكمبيوتر.
بالنسبة إلى العديد من التطبيقات، يكفي استخدام مفتاح السهم والتنقل باستخدام علامات التبويب، ويتولّى إطار عمل Android معظم هذه العمليات تلقائيًا. على سبيل المثال، يمكن التركيز على عرض Button تلقائيًا، ومن المفترض أن يعمل التنقّل باستخدام لوحة المفاتيح بشكل عام بدون أي رمز إضافي. لتفعيل التنقّل باستخدام لوحة المفاتيح في طرق العرض التي لا يمكن التركيز عليها تلقائيًا، على المطوّرين وضع علامة عليها للإشارة إلى إمكانية التركيز عليها. يمكن إجراء ذلك آليًا أو في XML، كما يلي. لمزيد من المعلومات، يُرجى الاطّلاع على مستندات التعامل مع التركيز.
yourView.isFocusable = true
يمكنك بدلاً من ذلك ضبط السمة focusable في ملف التصميم:
android:focusable="true"
بعد تفعيل وضع التركيز، سينشئ إطار عمل Android عملية ربط تنقّل لجميع طرق العرض القابلة للتركيز استنادًا إلى موضعها. عادةً ما يعمل هذا الإجراء على النحو المتوقّع ولا يلزم اتّخاذ أي إجراء آخر. عندما لا يكون التعيين التلقائي صحيحًا بما يتناسب مع احتياجات التطبيق، يمكن إلغاؤه باتّباع الخطوات التالية:
// Arrow keys yourView.nextFocusLeftId = R.id.view_to_left yourView.nextFocusRightId = R.id.view_to_right yourView.nextFocusTopId = R.id.view_above yourView.nextFocusBottomId = R.id.view_below // Tab key yourView.nextFocusForwardId = R.id.next_view
من الممارسات الجيدة محاولة الوصول إلى كل جزء من وظائف تطبيقك قبل كل إصدار باستخدام لوحة المفاتيح فقط. يجب أن يكون من الممكن الوصول إلى الإجراءات الأكثر شيوعًا بدون استخدام الماوس أو اللمس.
ملاحظة: تذكَّر أنّ إتاحة استخدام لوحة المفاتيح قد تكون ضرورية للمستخدمين الذين لديهم احتياجات متعلّقة بتسهيل الاستخدام.
ضغطات المفاتيح
بالنسبة إلى إدخال النصوص الذي ستتعامل معه لوحة مفاتيح افتراضية على الشاشة (طريقة إدخال) مثل EditText، يجب أن تتصرف التطبيقات على النحو المتوقّع على ChromeOS بدون أي عمل إضافي من المطوّر. بالنسبة إلى ضغطات المفاتيح التي لا يمكن توقّعها من خلال إطار العمل، ستحتاج التطبيقات إلى التعامل مع السلوك بنفسها. وينطبق ذلك بشكل خاص على التطبيقات التي تتضمّن طرق عرض مخصّصة.
وتتضمّن بعض الأمثلة تطبيقات الدردشة التي تستخدم مفتاح Enter لإرسال رسالة، وتطبيقات الوسائط التي تبدأ/توقف التشغيل باستخدام مفتاح المسافة، والألعاب التي تتحكّم في الحركة باستخدام المفاتيح w وa وs وd.
تتجاهل معظم التطبيقات الحدث onKeyUp وتضيف السلوك المتوقّع لكل رمز مفتاح تم استلامه، وذلك على النحو التالي.
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when (keyCode) { KeyEvent.KEYCODE_ENTER -> { sendChatMessage() true } KeyEvent.KEYCODE_SPACE -> { playOrPauseMedia() true } else -> super.onKeyUp(keyCode, event) } }
يؤدي استخدام onKeyUp إلى منع التطبيقات من تلقّي أحداث متعدّدة في حال الضغط على مفتاح أو تركه ببطء. يمكن للألعاب والتطبيقات التي تتطلّب من المستخدمين الضغط مع الاستمرار على مفاتيح لوحة المفاتيح البحث عن الحدث onKeyDown.
استنادًا إلى احتياجات التطبيق، يؤدي إلغاء onKeyUp للنشاط بأكمله عادةً إلى توفير السلوك المطلوب. إذا لزم الأمر، يمكن إضافة onKeyListener إلى طريقة عرض معيّنة بدلاً من ذلك. على سبيل المثال، قد يستمع التطبيق إلى مفتاح Enter فقط في حقل EditText معيّن، وليس في النشاط، وذلك لتنفيذ وظيفة الإرسال فقط عندما يكتب المستخدم في مربّع محادثة.
عند إضافة إمكانية استخدام لوحة المفاتيح، اتّبِع المستندات المتعلقة بالتعامل مع لوحة المفاتيح في Android.
الاختصارات
من المتوقّع أن تتوفّر اختصارات شائعة تستند إلى ctrl وalt وshift في بيئات الكمبيوتر المكتبي. وإذا لم ينفّذ التطبيق هذه الإجراءات، قد يشعر المستخدمون بالإحباط وأنّ التجربة غير مكتملة. يقدّر المستخدمون المتقدّمون أيضًا الاختصارات الخاصة بالمهام التي يتم تنفيذها بشكل متكرر في التطبيق. تسهّل الاختصارات استخدام التطبيق وتميّزه عن التطبيقات التي لا تتضمّن اختصارات.
تشمل بعض الاختصارات الشائعة الحفظ (ctrl+s) والتراجع (ctrl+z) والإعادة (ctrl+shift+z). للحصول على مثال على بعض الاختصارات الأكثر تقدّمًا، اطّلِع على قائمة مفاتيح الاختصارات في VLC Media Player.
يمكن تنفيذ الاختصارات باستخدام dispatchKeyShortcutEvent. يؤدي ذلك إلى اعتراض جميع مجموعات المفاتيح الوصفية (alt وctrl وshift) لرمز مفتاح معيّن. للبحث عن مفتاح وصف محدّد، استخدِم KeyEvent.isCtrlPressed() أو KeyEvent.isShiftPressed() أو KeyEvent.isAltPressed() أو KeyEvent.hasModifiers().
يمكن أن يؤدي فصل رمز الاختصار عن معالجة ضغطات المفاتيح الأخرى (مثل onKeyUp أو onKeyDown) إلى تسهيل صيانة الرمز والحفاظ على القبول التلقائي لمفاتيح التعريف بدون الحاجة إلى تنفيذ عمليات التحقّق من مفاتيح التعريف يدويًا في كل حالة. قد يكون السماح بجميع مجموعات المفاتيح الوصفية أكثر ملاءمةً للمستخدمين الذين اعتادوا على تنسيقات لوحات مفاتيح وأنظمة تشغيل مختلفة.
override fun dispatchKeyShortcutEvent(event: KeyEvent): Boolean { return when (event.keyCode) { KeyEvent.KEYCODE_O -> { openFile() // Ctrl+O, Shift+O, Alt+O true } KeyEvent.KEYCODE_Z-> { if (event.isCtrlPressed) { if (event.isShiftPressed) { redoLastAction() // Ctrl+Shift+Z pressed true } else { undoLastAction() // Ctrl+Z pressed true } } } else -> { return super.dispatchKeyShortcutEvent(event) } } }
يمكنك أيضًا تنفيذ الاختصارات في onKeyUp من خلال البحث عن KeyEvent.isCtrlPressed() أو KeyEvent.isShiftPressed() أو KeyEvent.isAltPressed() بالطريقة نفسها. قد يكون من الأسهل الحفاظ على هذا النوع من السلوك إذا كان السلوك الوصفي عبارة عن تعديل لسلوك التطبيق بدلاً من اختصار. على سبيل المثال، عندما يعني w "المشي إلى الأمام" وshift+w يعني "الركض إلى الأمام".
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when(keyCode) { KeyEvent.KEYCODE_W-> { if (event.isShiftPressed) { if (event.isCtrlPressed) { flyForward() // Ctrl+Shift+W pressed true } else { runForward() // Shift+W pressed true } } else { walkForward() // W pressed } } else -> super.onKeyUp(keyCode, event) } }
إمكانية استخدام الماوس ولوحة اللمس
يتعامل ChromeOS تلقائيًا مع معظم أحداث الماوس ولوحة اللمس لتعمل مثل أحداث اللمس على هاتف Android. ويشمل ذلك التمرير باستخدام إصبعَين على لوحة اللمس أو عجلة الماوس. بشكل عام، تحتاج معظم التطبيقات إلى التعامل مع ثلاثة أحداث فقط تركّز على أجهزة الكمبيوتر المكتبي: النقر بزر الماوس الأيمن والتمرير والسحب والإفلات.
النقر بزر الماوس الأيمن
يجب أن تتفاعل أيضًا أي إجراءات تؤدي إلى عرض قائمة سياق في تطبيق، مثل النقر مع الاستمرار على عنصر قائمة، مع أحداث النقر بزر الماوس الأيمن. للتعامل مع أحداث النقر بزر الماوس الأيمن، يجب أن تسجّل التطبيقات View.OnContextClickListener. للحصول على تفاصيل حول إنشاء قائمة سياقية، يُرجى الاطّلاع على مستندات القائمة السياقية في Android.
yourView.setOnContextClickListener { view -> showContextMenu() true }
ملاحظة: أي طرق عرض تم تسجيلها لقائمة السياق باستخدام Activity.registerForContextMenu() يجب أن تعمل تلقائيًا مع كل من الضغط مع الاستمرار والنقر بزر الماوس الأيمن بدون الحاجة إلى تسجيل أداة معالجة نقرات قائمة السياق.
تمرير مؤشر الماوس
يمكن للمطوّرين جعل تنسيقات تطبيقاتهم تبدو أكثر سلاسة وأسهل في الاستخدام من خلال التعامل مع أحداث التمرير. وينطبق ذلك بشكل خاص على طرق العرض المخصّصة. في ما يلي مثالان شائعان على ذلك:
- إعلام المستخدمين بما إذا كان العنصر يتضمّن سلوكًا تفاعليًا، مثل أن يكون قابلاً للنقر أو التعديل، وذلك من خلال تغيير رمز مؤشر الماوس
- إضافة ملاحظات مرئية إلى العناصر في قائمة أو شبكة كبيرة عندما يمر المؤشر فوقها
// Change the icon to a "hand" pointer on hover, // Highlight the view by changing the background. yourView.setOnHoverListener { view, _ -> addVisualHighlighting(true) view.pointerIcon = PointerIcon.getSystemIcon(applicationContext, PointerIcon.TYPE_HAND) false // listener did not consume the event. }
السحب والإفلات
في بيئة النوافذ المتعددة، يتوقّع المستخدمون أن يتمكّنوا من سحب العناصر وإفلاتها بين التطبيقات. وينطبق ذلك على أجهزة ChromeOS والأجهزة اللوحية والهواتف والأجهزة القابلة للطي في وضع تقسيم الشاشة.
على المطوّرين مراعاة ما إذا كان من المحتمل أن يسحب المستخدمون عناصر إلى تطبيقاتهم. تتضمّن بعض الأمثلة الشائعة ما يلي: يجب أن تتوقّع أدوات تعديل الصور تلقّي الصور، ويجب أن تتوقّع مشغّلات الصوت تلقّي ملفات الصوت، ويجب أن تتوقّع برامج الرسم تلقّي الصور.
لإضافة ميزة السحب والإفلات، اتّبِع مستندات السحب والإفلات في Android واطّلِع على منشور مدونة ChromeOS هذا.
اعتبارات خاصة بنظام التشغيل ChromeOS
-
للتعامل مع الملفات من تطبيق "الملفات" على ChromeOS، ابحث عن نوع MIME
application/x-arc-uri-list -
تذكَّر طلب الإذن باستخدام
requestDragAndDropPermissionsللوصول إلى العناصر التي تم سحبها من خارج التطبيق -
يجب أن يتضمّن العنصر العلامة
View.DRAG_FLAG_GLOBALليتم سحبه إلى تطبيقات أخرى
إمكانية اختيار عناصر متعددة
إذا كان تطبيقك يحتوي على قوائم أو شبكات، فكِّر في ما إذا كان المستخدمون سيستفيدون من إتاحة إمكانية التحديد المتعدد. تتضمّن تجربة الاختيار المتعدّد العالية الجودة باستخدام الماوس ولوحة اللمس غالبًا ميزات مثل اختيار النطاق. قد يكون تنفيذ ذلك بنفسك أمرًا صعبًا، ولكن يمكنك استخدام مكتبة Recyclerview Selection.
التوافق المتقدّم مع المؤشر
يجب أن تتّبع التطبيقات التي تتعامل بشكل متقدّم مع إدخال الماوس ولوحة اللمس مستندات Android الخاصة View.onGenericMotionEvent() وأن تستخدم MotionEvent.getSource() للتمييز بين SOURCE_MOUSE وSOURCE_TOUCHSCREEN.
افحص MotionEvent لتنفيذ السلوك المطلوب:
-
تؤدي الحركة إلى إنشاء
ACTION_HOVER_MOVEحدث -
تنشئ الأزرار الحدثَين
ACTION_BUTTON_PRESSوACTION_BUTTON_RELEASE. يمكنك أيضًا التحقّق من الحالة الحالية لجميع أزرار الماوس أو لوحة اللمس باستخدامgetButtonState(). -
يؤدي التمرير باستخدام عجلة الماوس إلى إنشاء أحداث
ACTION_SCROLL
قلم الشاشة
تتضمّن العديد من أجهزة Chromebook قلم شاشة، وتتعامل تطبيقات Android مع هذا القلم كإدخال عبر شاشة تعمل باللمس. قد تتضمّن بعض الأجهزة أيضًا لوحة رسم USB أو بلوتوث، مثل Wacom Intuos. يمكن لتطبيقات Android تلقّي إدخال عبر البلوتوث، ولكنّها لن تعمل مع الإدخال عبر USB.
يتم تسجيل حدث قلم الشاشة كحدث شاشة تعمل باللمس باستخدام View.onTouchEvent() أو View.onGenericMotionEvent()، ويتضمّن MotionEvent.getSource() من النوع SOURCE_STYLUS. سيحتوي MotionEvent أيضًا على بيانات إضافية:
-
ستعرض
MotionEvent.getToolType()القيمةTOOL_TYPE_FINGERأوTOOL_TYPE_STYLUSأوTOOL_TYPE_ERASERاستنادًا إلى الأداة التي لامست السطح -
ستعرض السمة
MotionEvent.getPressure()مقدار الضغط المادي الذي تمارسه على قلم الشاشة، إذا كان ذلك متاحًا. -
MotionEvent.getAxisValue()معMotionEvent.AXIS_TILTوMotionEvent.AXIS_ORIENTATIONاللذين يمكن استخدامهما لقراءة ميل القلم وموضعه، إذا كان ذلك متاحًا
النقاط السابقة
تجمّع حزمة Android أحداث الإدخال وتسلّمها مرة واحدة لكل إطار. يمكن لقلم الشاشة إرسال الأحداث بترددات أعلى بكثير من الشاشة. عند إنشاء تطبيقات رسم، من المهم التحقّق من الأحداث التي قد تكون في الماضي القريب باستخدام واجهات برمجة التطبيقات getHistorical:
-
MotionEvent.getHistoricalX() -
MotionEvent.getHistoricalY() -
MotionEvent.getHistoricalPressure() -
MotionEvent.getHistoricalAxisValue()
ميزة "رفض لمس راحة اليد"
يحاول نظام التشغيل ChromeOS التعرّف على الحالات التي يستند فيها راحة يد المستخدم على الشاشة التي تعمل باللمس. ومع ذلك، لا يكون ذلك ممكنًا دائمًا. في بعض الأحيان، قد يتم إرسال حدث لمس إلى التطبيق قبل أن يتعرّف نظام التشغيل عليه على أنّه لمسة راحة اليد. في هذه الحالة، سيتم إلغاء اللمسات من خلال تسجيل حدث ACTION_CANCEL.
يُعلم هذا الحدث التطبيق بأنّ بعض اللمسات غير صالحة ويجب التراجع عن جميع التفاعلات الناتجة عن هذه اللمسات. على سبيل المثال، قد يرسم تطبيق رسم خطوطًا جديدة مؤقتًا فور تلقّيها لتوفير أقل وقت استجابة، ولكنّه لا يلتزم بها بشكل دائم على لوحة الرسم إلا بعد الانتهاء من سلسلة اللمسات بشكل سليم. إذا تم إلغاء أحداث اللمس في هذه الأثناء، يمكن محو الخطوط المؤقتة.
ملاحظة: إحدى طرق تقليل أحداث راحة اليد والأصابع غير الضرورية في تطبيقات الرسم والكتابة هي توفير إعداد لواجهة المستخدم يؤدي إلى إيقاف الرسم باستخدام اللمس، واستخدام أحداث قلم الشاشة فقط للرسم عند تفعيل هذا الوضع.
تطبيقات تدوين الملاحظات
يتضمّن ChromeOS هدفًا خاصًا يعرض تطبيقات تدوين الملاحظات المسجَّلة للمستخدمين. لتسجيل تطبيق كتطبيق لتدوين الملاحظات، أضِف ما يلي إلى ملف البيان Android:
<intent-filter> <action android:name="org.chromium.arc.intent.action.CREATE_NOTE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>
عند تسجيل تطبيق، يمكن للمستخدم اختياره كتطبيق تدوين الملاحظات التلقائي. وعند طلب إنشاء ملاحظة جديدة، يجب أن ينشئ التطبيق ملاحظة فارغة جاهزة للكتابة باستخدام القلم. عندما يريد المستخدم إضافة تعليق توضيحي إلى صورة (مثل لقطة شاشة أو صورة تم تنزيلها)، يتم تشغيل التطبيق مع ClipData يحتوي على عنصر واحد أو أكثر مع معرّفات موارد منتظمة (URI) content://. يجب أن ينشئ التطبيق ملاحظة تستخدم الصورة الأولى المرفقة كصورة خلفية، وأن يدخل في وضع يمكن للمستخدم من خلاله الرسم باستخدام قلم.
اختبار نوايا تدوين الملاحظات بدون قلم شاشة
لاختبار ما إذا كان التطبيق يستجيب بشكل صحيح لطلبات تدوين الملاحظات بدون قلم نشط، استخدِم الطريقة التالية لعرض خيارات تدوين الملاحظات:
- التبديل إلى وضع المطوّرين وجعل الجهاز قابلاً للكتابة
-
اضغط على
ctrl+alt+f2لفتح نافذة طرفية -
نفِّذ الأمر
sudo vi /etc/chrome_dev.conf -
اضغط على
iلتعديل--ash-enable-paletteوإضافته إلى سطر جديد في نهاية الملف -
احفظ التغييرات من خلال الضغط على
Escثم كتابة:وwوqوالضغط علىEnter -
اضغط على
ctrl+alt+f1للرجوع إلى واجهة مستخدم ChromeOS العادية
من المفترض أن تظهر الآن قائمة القلم في الرف:
- انقر على زر القلم في الرف واختَر ملاحظة جديدة. من المفترض أن يؤدي هذا إلى فتح ملاحظة رسم فارغة
- خُذ لقطة شاشة. من الرف، انقر على زر القلم > تصوير الشاشة أو نزِّل صورة. يجب أن يتوفّر الخيار "إضافة تعليق توضيحي إلى الصورة" في الإشعار. سيؤدي ذلك إلى تشغيل التطبيق مع توفّر الصورة لتتم إضافة التعليقات التوضيحية إليها.
ذراع التحكّم في الألعاب
تتوافق أجهزة Chromebook مع ما يصل إلى أربعة أذرع تحكّم في الألعاب. على المطوّرين استخدام واجهات برمجة التطبيقات الخاصة بأذرع التحكّم في الألعاب العادية على Android للتعامل معها.
يتم ربط الأزرار بالقيم الشائعة باتّباع عملية ربط شائعة. لسوء الحظ، لا يلتزم جميع مصنّعي وحدات التحكّم في الألعاب باتّفاقيات الربط نفسها. يمكنك تقديم تجربة أفضل بكثير إذا سمحت للمستخدمين باختيار عمليات ربط مختلفة لأزرار وحدات التحكّم الشائعة.
وضع ترجمة الإدخال
يوفّر ChromeOS تلقائيًا وضع ترجمة الإدخال. بالنسبة إلى معظم تطبيقات Android، يساعد هذا الوضع التطبيقات في العمل على النحو المتوقّع في بيئة سطح المكتب. وتشمل بعض الأمثلة تفعيل التمرير بإصبعَين على لوحة اللمس تلقائيًا، والتمرير باستخدام عجلة الماوس، وربط إحداثيات العرض الأولية بإحداثيات النافذة. بشكل عام، لا يحتاج مطوّرو التطبيقات إلى تنفيذ أي من هذه السلوكيات بأنفسهم.
إذا كان التطبيق ينفّذ سلوك إدخال مخصّصًا، مثل تحديد إجراء مخصّص للضغط بإصبعَين على لوحة اللمس، أو إذا كانت ترجمات الإدخال هذه لا توفّر أحداث الإدخال التي يتوقّعها التطبيق، يمكنك إيقاف وضع ترجمة الإدخال عن طريق إضافة العلامة التالية إلى ملف البيان في Android:
<uses-feature android:name="android.hardware.type.pc" android:required="false" />