المواد التالية مخصّصة لمطوّري التطبيقات.
لإتاحة استخدام التطبيق بشكل منتظم، يجب:
- ضَع "
FocusParkingView
" في تنسيق النشاط المعنيّ. - التأكّد من أنّ المشاهدات التي يمكن التركيز عليها (أو التي لا يمكن التركيز عليها)
- استخدِم
FocusArea
للالتفاف حول كل العروض القابلة للتركيز، باستثناءFocusParkingView
يتم تفصيل كل من هذه المهام أدناه، بعد إعداد بيئتك من أجل تطوير التطبيقات التي تتيح وحدة تحكُّم دورانية.
إعداد وحدة تحكّم دوّارة
قبل أن تتمكّن من البدء في تطوير التطبيقات التي تستخدم دوّارًا، يجب استخدام وحدة تحكّم دوّارة أو احتياطي. تتوفر لك الخيارات الموضحة أدناه.
المحاكي
source build/envsetup.sh && lunch car_x86_64-userdebug m -j emulator -wipe-data -no-snapshot -writable-system
ويمكنك أيضًا استخدام aosp_car_x86_64-userdebug
.
للوصول إلى وحدة التحكّم الدوّارة التي تمّت محاكاتها:
- انقر على النقاط الثلاث أسفل شريط الأدوات:
- اختَر دوّارة سيارة في نافذة عناصر التحكّم الموسّعة:
لوحة مفاتيح USB
- عليك توصيل لوحة مفاتيح USB بجهازك الذي يعمل بنظام التشغيل Android Automotive (AAOS). في بعض الحالات، يمنع هذا الإجراء ظهور لوحة المفاتيح على الشاشة.
- يجب استخدام الإصدار
userdebug
أوeng
. - تفعيل فلترة الأحداث الرئيسية:
adb shell settings put secure android.car.ROTARY_KEY_EVENT_FILTER 1
- انظر الجدول أدناه للعثور على المفتاح المقابل لكل إجراء:
المفتاح وظيفة دورانية Q تدوير عكس عقارب الساعة E تدوير في اتجاه عقارب الساعة A دفع إلى اليسار D دفع لليمين W دفع لأعلى S دفع إلى الأسفل F أو فاصلة الزر الأوسط R أو Esc زر الرجوع
أوامر ADB
يمكنك استخدام أوامر car_service
لإدخال أحداث الإدخال باستخدام وحدة تحكُّم دورانية. وهذه الأوامر
يمكن تشغيلها على الأجهزة التي تعمل بنظام التشغيل Android Automotive (AAOS) أو على محاكي.
أوامر Car_service | إدخال البيانات عبر وحدة تحكُّم دورانية |
---|---|
adb shell cmd car_service inject-rotary |
تدوير عكس عقارب الساعة |
adb shell cmd car_service inject-rotary -c true |
تدوير في اتجاه عقارب الساعة |
adb shell cmd car_service inject-rotary -dt 100 50 |
تدوير عدة مرات عكس اتجاه عقارب الساعة (قبل 100 ملي ثانية و50 ملي ثانية) |
adb shell cmd car_service inject-key 282 |
دفع إلى اليسار |
adb shell cmd car_service inject-key 283 |
دفع لليمين |
adb shell cmd car_service inject-key 280 |
دفع لأعلى |
adb shell cmd car_service inject-key 281 |
دفع إلى الأسفل |
adb shell cmd car_service inject-key 23 |
النقر على الزر الأوسط |
adb shell input keyevent inject-key 4 |
النقر على زر الرجوع |
وحدة تحكّم دوّارة للمصنّع الأصلي للجهاز
عندما تكون وحدة التحكم الدوارة قيد التشغيل، فهذه هي واقعيًا. وهو مفيد بشكل خاص لاختبار الدوران السريع.
عرض التركيز في موقف السيارات
FocusParkingView
هو عرض شفاف في
مكتبة واجهة مستخدم السيارة (car-ui-library).
تستخدِمه خدمة RotaryService
لإتاحة التنقّل باستخدام وحدة التحكّم الدوّارة.
يجب أن يكون FocusParkingView
هو العرض الأول القابل للتركيز
في التخطيط. يجب وضعه خارج جميع FocusArea
. يجب أن تحتوي كل نافذة على علامة
FocusParkingView
إذا كنت تستخدم بالفعل التخطيط الأساسي لمكتبة السيارة،
الذي يحتوي على FocusParkingView
، لا حاجة إلى إضافة علامة أخرى.
FocusParkingView
يظهر أدناه مثال على FocusParkingView
في
RotaryPlayground
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.android.car.ui.FocusParkingView android:layout_width="wrap_content" android:layout_height="wrap_content"/> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout>
في ما يلي أسباب احتياجك إلى FocusParkingView
:
- لا يمحو Android التركيز تلقائيًا عند ضبط التركيز في نافذة أخرى. إذا كنت
حاول إزالة التركيز في النافذة السابقة، سيعيد Android تركيز طريقة العرض في تلك النافذة،
يؤدي إلى التركيز على نافذتين في وقت واحد. جارٍ إضافة
FocusParkingView
مع كل نافذة إلى حل هذه المشكلة. طريقة العرض هذه شفافة وإبراز تركيزها التلقائي. ويتم إيقافه، حتى لا يظهر للمستخدم سواء تم التركيز عليه أم لا. بإمكان "RotaryService
" التركيز على الفيديو ليتمكّن "RotaryService
" من إيقاف التركيز عليه. لإزالة تمييز التركيز. - في حال وجود
FocusArea
واحد فقط في النافذة الحالية، يؤدي ذلك إلى تدوير وحدة التحكّم. فيFocusArea
إلى نقل التركيز من خلالRotaryService
من العرض على اليمين إلى العرض على اليسار (والعكس صحيح). جارٍ إضافة هذا العرض إلى كل نافذة إلى حل المشكلة. عندما يتم تحديد التركيز من قِبل "RotaryService
" هوFocusParkingView
، فيمكن أن يحدد الالتفاف المرصود وعند هذه النقطة، يتم تجنب الالتفاف من خلال عدم تحريك التركيز. - عندما يشغِّل عنصر التحكّم الدوار أحد التطبيقات، يركّز Android على أول عرض يمكن التركيز عليه،
وهو دائمًا
FocusParkingView
.FocusParkingView
ويحدد العرض الأمثل للتركيز عليه ثم يطبق التركيز.
طرق العرض التي يمكن التركيز عليها
يعتمد RotaryService
على إطار عمل Android
الحالي
مفهوم تركيز الرؤية، يعود تاريخه إلى الوقت الذي كانت فيه الهواتف مزودة بلوحات مفاتيح خارجية ولوحات D.
تمّت إعادة استخدام سمة android:nextFocusForward
الحالية كوحدة تحكّم دورانية.
(يُرجى الاطّلاع على تخصيص FocusArea)، ولكن
android:nextFocusLeft
، android:nextFocusRight
،
android:nextFocusUp
وandroid:nextFocusDown
ليسا كذلك.
يركّز RotaryService
فقط على المشاهدات التي يمكن التركيز عليها. تتميز بعض طرق العرض
مثل Button
يمكن التركيز عليها عادةً. سمات أخرى، مثل TextView
وViewGroup
عادةً لا يتم ذلك. يمكن التركيز تلقائيًا على مرات العرض القابلة للنقر، ويتم تلقائيًا
قابل للنقر عندما يكون لديهم مستمع للنقرة. إذا نتج عن هذا المنطق التلقائي البيانات
لن تحتاج إلى ضبط قابلية التركيز في العرض بشكل صريح. إذا لم يكن المنطق التلقائي
إلى إمكانية التركيز المطلوبة، اضبط السمة android:focusable
على
true
أو false
، أو ضبط إمكانية تركيز العرض آليًا باستخدام
View.setFocusable(boolean)
لكي يتمكن RotaryService
من التركيز عليه، يجب أن
استيفاء المتطلبات التالية:
- يمكن التركيز عليه
- مفعّلة
- المراجعات المعروضة
- أن تشتمل على قيم غير صفرية للعرض والارتفاع
إذا كانت طريقة العرض لا تستوفي كل هذه المتطلبات، مثل زر يمكن التركيز عليه ولكنه غير مفعّل،
لا يمكن للمستخدم استخدام التحكم الدوار للتركيز عليها. إذا كنت تريد التركيز على طرق العرض غير المفعّلة،
ننصحك باستخدام حالة مخصّصة بدلاً من android:state_enabled
للتحكّم في كيفية
بدون الإشارة إلى أنّ نظام التشغيل Android يجب أن يعتبره غير مفعّل. يمكن لتطبيقك إبلاغ
المستخدم بسبب تعطيل العرض عند النقر عليه. ويوضّح القسم التالي كيفية إجراء ذلك.
حالة مخصَّصة
لإضافة حالة مخصّصة:
- لإضافة سمة مخصّصة
على طريقة العرض على سبيل المثال، لإضافة حالة
state_rotary_enabled
مخصّصة إلى صف واحد (CustomView
) لعرض الصف، استخدام:<declare-styleable name="CustomView"> <attr name="state_rotary_enabled" format="boolean" /> </declare-styleable>
- لتتبع هذه الحالة، أضف متغير مثيل إلى العرض مع طرق الموصّل:
private boolean mRotaryEnabled; public boolean getRotaryEnabled() { return mRotaryEnabled; } public void setRotaryEnabled(boolean rotaryEnabled) { mRotaryEnabled = rotaryEnabled; }
- لقراءة قيمة السمة عند إنشاء طريقة العرض:
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomView); mRotaryEnabled = a.getBoolean(R.styleable.CustomView_state_rotary_enabled);
- في فئة العرض، يمكنك إلغاء طريقة
onCreateDrawableState()
، ثم وإضافة الحالة المخصصة، عندما يكون ذلك مناسبًا. مثل:@Override protected int[] onCreateDrawableState(int extraSpace) { if (mRotaryEnabled) extraSpace++; int[] drawableState = super.onCreateDrawableState(extraSpace); if (mRotaryEnabled) { mergeDrawableStates(drawableState, { R.attr.state_rotary_enabled }); } return drawableState; }
- ضبط أداء معالج النقرات في طريقة العرض بشكل مختلف حسب حالته على سبيل المثال،
قد لا يفعل معالج النقرات أي شيء أو قد ينبثق عندما
تم
false
ميزةmRotaryEnabled
. - لجعل الزر يبدو غير مفعّل، استخدِم إمكانية رسم خلفية العرض في
app:state_rotary_enabled
بدلاً منandroid:state_enabled
وإذا لم يكن متوفّرًا لديك من قبل، عليك إضافة ما يلي:xmlns:app="http://schemas.android.com/apk/res-auto"
- إذا تم إيقاف العرض في أي تنسيقات، استبدِل
android:enabled="false"
بـapp:state_rotary_enabled="false"
ثم أضِف مساحة الاسمapp
على النحو الوارد أعلاه. - إذا كان العرض غير مفعَّل آليًا، يمكنك استبدال المكالمات إلى
setEnabled()
. مع مكالمات إلىsetRotaryEnabled()
.
منطقة التركيز
استخدِم "FocusAreas
" لتقسيم طرق العرض التي يمكن التركيز عليها إلى كتل من أجل تسهيل التنقّل
أسهل وأن تكون متسقة مع التطبيقات الأخرى. على سبيل المثال، إذا كان تطبيقك يحتوي على شريط أدوات، فإن شريط الأدوات
يجب أن يكون في FocusArea
منفصل عن باقي التطبيق. أشرطة علامات التبويب
يجب أيضًا فصل عناصر التنقل الأخرى عن بقية التطبيق. القوائم الكبيرة
يجب أن يكون لها FocusArea
خاصة بها بشكل عام. وإذا لم يكن كذلك، يجب على المستخدمين عرض الإعلانات بالتناوب.
القائمة بأكملها للوصول إلى بعض طرق العرض.
FocusArea
هي فئة فرعية من LinearLayout
في مكتبة واجهة المستخدم للسيارات.
عند تفعيل هذه الميزة، يبرز FocusArea
بشكل بارز عندما تكون إحدى
والأحفاد لدينا التركيز. لمزيد من المعلومات، يُرجى مراجعة
التركيز على تخصيص اللحظات المميّزة.
عند إنشاء كتلة تنقل في ملف التخطيط، إذا كنت تنوي استخدام
LinearLayout
كحاوية لتلك المجموعة، استخدِم FocusArea
بدلاً منها.
في الحالات الأخرى، يمكنك لف المربّع باستخدام FocusArea
.
لا تدمج FocusArea
في FocusArea
آخر.
يؤدي القيام بذلك إلى سلوك تنقل غير محدد. تأكد من أن جميع طرق العرض التي يمكن التركيز عليها
متداخلة في FocusArea
.
مثال على FocusArea
في
يتم عرض RotaryPlayground
أدناه:
<com.android.car.ui.FocusArea android:layout_margin="16dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true"> </EditText> </com.android.car.ui.FocusArea>
يعمل FocusArea
على النحو التالي:
- عند التعامل مع إجراءات التدوير والتذكير، يبحث
RotaryService
عن مثيلات منFocusArea
في التدرج الهرمي لطريقة العرض. - عند تلقّي حدث تدوير، ينقل
RotaryService
التركيز إلى حدث آخر. الملف الشخصي الذي يمكن التركيز عليه فيFocusArea
نفسها - عند تلقّي تذكير تلقائي، يتم نقل التركيز من قِبل "
RotaryService
" إلى طريقة عرض أخرى. يمكن أن يركّز على عنصرFocusArea
آخر (متجاور عادةً).
إذا لم تُدرِج أي FocusAreas
في التنسيق، تتم معالجة طريقة العرض الجذر.
كمجال تركيز ضمني لا يمكن للمستخدم الوكز للتنقل داخل التطبيق. بدلاً من ذلك،
التنقل عبر كل طرق العرض القابلة للتركيز، والتي قد تكون ملائمة لمربعات الحوار.
تخصيص FocusArea
يمكن استخدام سمتَين عاديتَين في ميزة "العرض" لتخصيص التنقّل الدوّار:
- يسمح
android:nextFocusForward
لمطوِّري التطبيقات بتحديد عرض الإعلانات بالتناوب. بالترتيب في مجال التركيز. هذه هي السمة نفسها المستخدمة للتحكم في ترتيب التنقل بـ Tab التنقل باستخدام لوحة المفاتيح. لا تستخدم هذه السمة لإنشاء حلقة تكرار. بدلاً من ذلك، يمكنك استخدامapp:wrapAround
(انظر أدناه) لإنشاء حلقة. - يسمح
android:focusedByDefault
لمطوّري التطبيقات بتحديد عرض التركيز الافتراضي في النافذة. لا تستخدم هذه السمةapp:defaultFocus
(انظر أدناه) فيFocusArea
نفسه.
تحدِّد السمة FocusArea
أيضًا بعض السمات لتخصيص نظام التنقُّل الدوّار.
لا يمكن تخصيص مجالات التركيز الضمنية باستخدام هذه السمات.
- (Android 11 QPR3 وAndroid 11 Car،
نظام التشغيل Android 12)
يمكن استخدامapp:defaultFocus
للأغراض التالية: تحديد رقم تعريف ملف شخصي تابع يمكن التركيز عليه، والذي يجب التركيز عليه عندما ينقر المستخدم يشير إلى "FocusArea
" كتذكير تلقائي. - (Android 11 QPR3 وAndroid 11 Car،
نظام التشغيل Android 12)
app:defaultFocusOverridesHistory
يمكن ضبطها علىtrue
لجعل طريقة العرض المحدّدة أعلاه تركِّز حتى إذا كان السابقة للإشارة إلى وجهة نظر أخرى في هذهFocusArea
التي تم التركيز عليها. - (نظام التشغيل Android 12)
استخدِمapp:nudgeLeftShortcut
وapp:nudgeRightShortcut
app:nudgeUpShortcut
وapp:nudgeDownShortcut
لتحديد رقم تعريف ملف شخصي تابع يمكن التركيز عليه، والذي يجب التركيز عليه عند يقوم المستخدم بتذكيرك في اتجاه معين. لمزيد من المعلومات، يمكنك الاطّلاع على محتوى ادفع الاختصارات أدناه.(Android 11 QPR3 وAndroid 11 Car، متوقّفة نهائيًا في نظام التشغيل Android 12)
app:nudgeShortcut
وapp:nudgeShortcutDirection
يتوافق مع اختصار تذكير تلقائي واحد فقط. - (Android 11 QPR3 وAndroid 11 Car،
نظام التشغيل Android 12)
لتفعيل ميزة التدوير أثناء الدوران فيFocusArea
،app:wrapAround
يمكن ضبطها علىtrue
. وتُستخدم هذه الطريقة عادةً عندما يتمّ ترتيب المشاهد في أو بيضاوي الشكل. - (Android 11 QPR3 وAndroid 11 Car،
نظام التشغيل Android 12)
لضبط المساحة المتروكة للتمييز في هذهFocusArea
، استخدامapp:highlightPaddingStart
،app:highlightPaddingEnd
وapp:highlightPaddingTop
app:highlightPaddingBottom
،app:highlightPaddingHorizontal
، وapp:highlightPaddingVertical
. - (Android 11 QPR3 وAndroid 11 Car،
نظام التشغيل Android 12)
لضبط الحدود المرصودة للسمةFocusArea
هذه لإيجاد هدف دفعة، استخدامapp:startBoundOffset
أوapp:endBoundOffset
app:topBoundOffset
،app:bottomBoundOffset
،app:horizontalBoundOffset
وapp:verticalBoundOffset
. - (Android 11 QPR3 وAndroid 11 Car،
نظام التشغيل Android 12)
لتحديد معرّفFocusArea
المتجاورة (أو المناطق) في الاتجاهات المحددة، استخدمapp:nudgeLeft
وapp:nudgeRight
وapp:nudgeUp
وapp:nudgeDown
استخدِم هذا الخيار عند استخدام بحث هندسي بشكل تلقائي لم يتمكن من العثور على الهدف المطلوب.
يؤدي الدفع عادةً إلى التنقل بين FocusAreas. ولكن مع اختصارات التحفيز،
أحيانًا، يؤدي الدفع كتذكير ينتقل لأول مرة داخل FocusArea
بحيث قد يحتاج المستخدم إلى
على التوجيه مرتين للانتقال إلى FocusArea
التالية. اختصارات التذكيرات التلقائية مفيدة
عندما يحتوي FocusArea
على قائمة طويلة متبوعة
زر الإجراء العائم،
كما في المثال أدناه:
بدون اختصار التذكير التلقائي، سيتعين على المستخدم التدوير خلال القائمة بأكملها للوصول إلى FAB.
التركيز على تخصيص اللحظات المميّزة
كما هو موضح أعلاه، تستند RotaryService
إلى المفهوم الحالي لإطار عمل Android
عرض التركيز. عندما يجري المستخدم تدويرًا وتنبيهًا، يتم نقل التركيز باستخدام RotaryService
،
التركيز على وجهة نظر واحدة وعدم التركيز على أخرى. في نظام التشغيل Android، عند التركيز على العرض، في حال كان العرض:
- يتضمّن نظام Android نقطة تركيز خاصة به، ويرسم نقطة التركيز في طريقة العرض.
- لا يتم تحديد تمييز التركيز، ولا يتم إيقاف ميزة التركيز التلقائي، في نظام Android لرسم تمييز التركيز الافتراضي للعرض.
أما التطبيقات المصممة للعمل باللمس، فهي لا تحدد عادةً النقاط البارزة المناسبة.
يتوفّر إبراز التركيز التلقائي من خلال إطار عمل Android ويمكن تجاهله.
المصنّع الأصلي للجهاز. يحصل مطوّرو التطبيقات على هذا المظهر عندما يكون المظهر الذي يستخدمونه مشتقًا من
Theme.DeviceDefault
لتقديم تجربة مستخدِم متّسقة، يمكنك الاعتماد على التركيز التلقائي على التركيز كلما أمكن ذلك.
إذا كنت بحاجة إلى تسليط الضوء على بؤرة مخصّصة (على سبيل المثال، شكل دائري أو شكل دوّار)، أو إذا كنت
باستخدام مظهر غير مشتق من Theme.DeviceDefault
، استخدِم مكتبة واجهة مستخدم السيارة.
والموارد لتحديد تمييز التركيز الخاص بك لكل طريقة عرض.
لتحديد تمييز تركيز مخصّص لإحدى طرق العرض، يمكنك تغيير الخلفية أو المقدّمة للرسم. من العرض إلى عنصر قابل للرسم يختلف عند تركيز العرض. عادةً ما ستغير الخلفية. العناصر التالية القابلة للرسم، إذا تم استخدامها كخلفية للعرض المربع، تُنتج تسليط الضوء على التركيز الدائري:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" android:state_pressed="true"> <shape android:shape="oval"> <solid android:color="@color/car_ui_rotary_focus_pressed_fill_color"/> <stroke android:width="@dimen/car_ui_rotary_focus_pressed_stroke_width" android:color="@color/car_ui_rotary_focus_pressed_stroke_color"/> </shape> </item> <item android:state_focused="true"> <shape android:shape="oval"> <solid android:color="@color/car_ui_rotary_focus_fill_color"/> <stroke android:width="@dimen/car_ui_rotary_focus_stroke_width" android:color="@color/car_ui_rotary_focus_stroke_color"/> </shape> </item> <item> <ripple...> ... </ripple> </item> </selector>
(Android 11 QPR3 وAndroid 11 Car، Android 12) مراجع موارد غامقة في النموذج أعلاه لتحديد الموارد المحددة في مكتبة واجهة المستخدم. يلغي المصنّع الأصلي للجهاز هذه الإعدادات لتكون متسقة باستخدام تمييز التركيز الافتراضي الذي يحددونه. يضمن ذلك أن يكون لون تمييز التركيز عرض خط الرسم، وما إلى ذلك، لا تتغير عندما يتنقل المستخدم بين طريقة عرض بتركيز مخصص التمييز وطريقة عرض بتمييز التركيز التلقائي. العنصر الأخير هو تموّج يُستخدم للمس. تظهر القيم التلقائية المستخدمة للموارد الغامقة كما يلي:
بالإضافة إلى ذلك، يتم استدعاء ميزة إبراز تركيز مخصَّص عند منح زر محدَّد لون الخلفية لجذب انتباه المستخدم، كما في المثال أدناه. هذا يمكن أن يصعب رؤية تمييز التركيز. في هذه الحالة، حدد تمييز تركيز مخصص باستخدام الألوان الثانوية:
- (Android 11 QPR3 وAndroid 11 Car،
نظام التشغيل Android 12)
car_ui_rotary_focus_fill_secondary_color
car_ui_rotary_focus_stroke_secondary_color
- (نظام التشغيل Android 12)
car_ui_rotary_focus_pressed_fill_secondary_color
car_ui_rotary_focus_pressed_stroke_secondary_color
مثلاً:
التركيز وليس المضغوط | التركيز والضغط |
التمرير الدوري
إذا كان تطبيقك يستخدم RecyclerView
، يجب استخدام
CarUiRecyclerView
بدلاً من ذلك. يضمن ذلك أن تكون واجهة المستخدم متوافقة مع
أخرى لأنّ تخصيص المصنّع الأصلي للجهاز ينطبق على جميع CarUiRecyclerView
.
إذا كانت جميع العناصر في قائمتك قابلة للتركيز، لن تحتاج إلى اتخاذ أي إجراء. ينقل "التنقل عبر الدوران" التركيز بين العناصر في القائمة ويتم تمرير القائمة لجعل العنصر الذي تم التركيز عليه حديثًا مرئيًا.
(Android 11 QPR3 وAndroid 11 Car،
نظام التشغيل Android 12)
إذا كان هناك مزيج من التركيز
وغير القابل للتركيز
الأخرى، أو إذا كانت جميع العناصر غير قابلة للتركيز، يمكنك تفعيل التمرير الدوري، وهو ما يتيح
استخدام المستخدم لوحدة التحكم الدوارة للتمرير تدريجيًا في القائمة دون تخطي
والعناصر غير القابلة للتركيز. لتفعيل التمرير الدوري، يجب ضبط app:rotaryScrollEnabled
.
إلى true
.
(Android 11 QPR3 وAndroid 11 Car،
نظام التشغيل Android 12)
يمكنك تفعيل التمرير الدوري في أي
عرض قابل للتمرير، بما في ذلك avCarUiRecyclerView
، مع
طريقة واحدة (setRotaryScrollEnabled()
) في CarUiUtils
. إذا قمت بذلك،
عليك إجراء ما يلي:
- جعل العرض القابل للتمرير قابلاً للتركيز عليه بحيث يمكن التركيز عليه عندما لا تكون يكون طرق العرض التابعة التي يمكن التركيز عليها مرئية،
- إيقاف ميزة إبراز التركيز التلقائي في العرض القابل للتمرير من خلال استدعاء
setDefaultFocusHighlightEnabled(false)
حتى يظهر العرض القابل للتمرير لا يبدو أنه مركز، - التأكد من التركيز على العرض القابل للتمرير قبل العناصر التابعة له من خلال استدعاء
setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS)
- الاستماع إلى MotionEvents باستخدام
SOURCE_ROTARY_ENCODER
AXIS_VSCROLL
أوAXIS_HSCROLL
للإشارة إلى المسافة التي يجب الانتقال إليها الاتجاه (من خلال العلامة).
عند تفعيل ميزة "التمرير الدوار" على CarUiRecyclerView
وتدوير المستخدم
إلى منطقة لا تتوفّر فيها طرق عرض قابلة للتركيز، يتغيّر شريط التمرير من اللون الرمادي إلى الأزرق، كما لو
للإشارة إلى التركيز على شريط التمرير. يمكنك تنفيذ تأثير مماثل إذا أردت.
أحداث Motion Events هي مثل تلك التي يتم إنشاؤها بواسطة عجلة تمرير على الماوس، باستثناء المصدر.
وضع التلاعب المباشر
عادةً، يتم نقل التذكيرات التلقائية والتدوير عبر واجهة المستخدم، بينما يضغط الزر الأوسط اتخذ إجراءً، على الرغم من أن هذا ليس هو الحال دائمًا. على سبيل المثال، إذا أراد أحد المستخدمين تعديل مستوى صوت المنبّه، فقد يستخدمون وحدة التحكّم الدوارة للانتقال إلى شريط تمرير مستوى الصوت الزر الأوسط، يجب تدوير وحدة التحكّم لضبط مستوى صوت المنبّه، ثم الضغط على زر الرجوع. للعودة إلى التنقل. ويُشار إلى ذلك بوضع التلاعب المباشر (DM). في هذه الدورة، يتم استخدام وحدة التحكم الدوارة للتفاعل مع العرض مباشرةً بدلاً من التنقل.
يمكنك تنفيذ الرسالة المباشرة بإحدى طريقتَين. إذا كنت تريد التعامل مع التدوير والعرض الذي تريده فقط
لمعالجة الردود على ACTION_SCROLL_FORWARD
ACTION_SCROLL_BACKWARD
AccessibilityEvent
بشكل مناسب، استخدِم
آلية بسيطة. وإذا لم تكن كذلك، يمكنك استخدام الآلية المتقدّمة.
والطريقة البسيطة هي الخيار الوحيد في نوافذ النظام؛ يمكن للتطبيقات استخدام أي من الطريقتين.
آلية بسيطة
(Android 11 QPR3 وAndroid 11 Car،
نظام التشغيل Android 12)
يجب أن يتصل التطبيق
DirectManipulationHelper.setSupportsRotateDirectly(View view, boolean enable)
يتعرّف RotaryService
عندما يكون المستخدم في وضع الرسالة المباشرة، ويدخل في وضع الرسالة المباشرة عندما يكون المستخدم.
يضغط على الزر الأوسط أثناء التركيز على العرض. عندما تكون في وضع الرسالة المباشرة، يتم تنفيذ عمليات التدوير
ACTION_SCROLL_FORWARD
أو ACTION_SCROLL_BACKWARD
ويخرج من وضع الرسالة المباشرة
عندما يضغط المستخدم على زر الرجوع. تعمل الآلية البسيطة على تبديل حالة
طريقة العرض عند الدخول إلى وضع الرسالة المباشرة والخروج منه.
لتوفير إشارة مرئية بأنّ المستخدم في وضع الرسالة المباشرة، يجب أن يظهر العرض بشكل مختلف
عند اختياره على سبيل المثال، يمكنك تغيير الخلفية عند
تم true
ميزة android:state_selected
.
الآلية المتقدّمة
يحدّد التطبيق وقت دخول "RotaryService
" إلى وضع الرسالة المباشرة والخروج منه. للحصول على
تجربة المستخدم، سيؤدي الضغط على زر "المركز" مع التركيز على طريقة عرض الرسالة المباشرة إلى الانتقال إلى وضع الرسالة المباشرة.
ويجب أن يخرج زر "الرجوع" من وضع الرسالة المباشرة. إذا لم يكن زر التوسيط و/أو التذكير التلقائي قيد الاستخدام،
يمكن أن تكون طرقًا بديلة للخروج من وضع الرسالة المباشرة. بالنسبة إلى تطبيقات مثل "خرائط Google"، يتوفّر زر لتمثيل
يمكن استخدام الرسالة المباشرة للدخول إلى وضع الرسالة المباشرة.
لإتاحة وضع الرسالة المباشرة المتقدّم، يمكن استخدام طريقة العرض التالية:
- (Android 11 QPR3 وAndroid 11 Car،
Android 12) يجب أن يستجيب إلى
KEYCODE_DPAD_CENTER
هو حدث للدخول في وضع الرسالة المباشرة والاستماع إلى حدثKEYCODE_BACK
للخروج من وضع الرسالة المباشرة الاتصال بـDirectManipulationHelper.enableDirectManipulationMode()
في كل حالة. للاستماع إلى هذه الأحداث، نفِّذ أحد الإجراءات التالية:- تسجيل
OnKeyListener
أو
- يمكنك تمديد العرض ثم إلغاء طريقة
dispatchKeyEvent()
.
- تسجيل
- يجب الاستماع إلى التذكيرات التلقائية (
KEYCODE_DPAD_UP
وKEYCODE_DPAD_DOWN
وKEYCODE_DPAD_LEFT
، أوKEYCODE_DPAD_RIGHT
) إذا كان ينبغي أن تكون طريقة العرض التعامل مع التذكيرات التلقائية. - يجب الاستماع إلى
MotionEvent
والحصول على عدد التدوير خلالAXIS_SCROLL
إذا أرادت طريقة العرض التعامل مع الدوران. وهناك العديد من الطرق لإجراء ذلك:- تسجيل
OnGenericMotionListener
- يمكنك تمديد العرض وإلغاء طريقة
dispatchTouchEvent()
.
- تسجيل
- لتجنُّب التوقّف في وضع الرسالة المباشرة، يجب الخروج من وضع الرسالة المباشرة عند عرض القسم "جزء" أو "النشاط". التي تنتمي إليها ليست تفاعلية.
- يجب توفير إشارة مرئية للإشارة إلى أنّ العرض في وضع الرسالة المباشرة.
فيما يلي نموذج من طريقة عرض مخصصة تستخدم وضع DM لتحريك وتكبير/تصغير الخريطة:
/** Whether this view is in DM mode. */ private boolean mInDirectManipulationMode;
/** Initializes the view. Called by the constructors. */ private void init() { setOnKeyListener((view, keyCode, keyEvent) -> { boolean isActionUp = keyEvent.getAction() == KeyEvent.ACTION_UP; switch (keyCode) { // Always consume KEYCODE_DPAD_CENTER and KEYCODE_BACK events. case KeyEvent.KEYCODE_DPAD_CENTER: if (!mInDirectManipulationMode && isActionUp) { mInDirectManipulationMode = true; DirectManipulationHelper.enableDirectManipulationMode(this, true); setSelected(true); // visually indicate DM mode } return true; case KeyEvent.KEYCODE_BACK: if (mInDirectManipulationMode && isActionUp) { mInDirectManipulationMode = false; DirectManipulationHelper.enableDirectManipulationMode(this, false); setSelected(false); } return true; // Consume controller nudge events only when in DM mode. // When in DM mode, nudges pan the map. case KeyEvent.KEYCODE_DPAD_UP: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(0f, -10f); return true; case KeyEvent.KEYCODE_DPAD_DOWN: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(0f, 10f); return true; case KeyEvent.KEYCODE_DPAD_LEFT: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(-10f, 0f); return true; case KeyEvent.KEYCODE_DPAD_RIGHT: if (!mInDirectManipulationMode) return false; if (isActionUp) pan(10f, 0f); return true; // Don't consume other key events. default: return false; } });
// When in DM mode, rotation zooms the map. setOnGenericMotionListener(((view, motionEvent) -> { if (!mInDirectManipulationMode) return false; float scroll = motionEvent.getAxisValue(MotionEvent.AXIS_SCROLL); zoom(10 * scroll); return true; })); }
@Override public void onPause() { if (mInDirectManipulationMode) { // To ensure that the user doesn't get stuck in DM mode, disable DM mode // when the fragment is not interactive (e.g., a dialog shows up). mInDirectManipulationMode = false; DirectManipulationHelper.enableDirectManipulationMode(this, false); } super.onPause(); }
يمكن العثور على مزيد من الأمثلة في
مشروع واحد (RotaryPlayground
).
عرض النشاط
عند استخدام ActivityView:
- يجب ألّا يكون التركيز على
ActivityView
. - (Android 11 QPR3 وAndroid 11 Car،
متوقفة نهائيًا في نظام التشغيل Android 11)
يجب أن يشتمل محتوىActivityView
علىFocusParkingView
كأول عرض يمكن التركيز عليه، وapp:shouldRestoreFocus
يجب أن تكون السمةfalse
. - يجب ألا يحتوي محتوى
ActivityView
علىandroid:focusByDefault
مشاهدة
بالنسبة إلى المستخدم، من المفترض ألا يكون لفئات ActivityView أي تأثير في التنقُّل باستثناء التركيز
لا يمكن للمناطق تضمين مشاهدات النشاط. بعبارة أخرى، لا يمكن أن يكون لديك مجال تركيز واحد
يشتمل على محتوى داخل وخارج ActivityView
. إذا لم تضِف
أي FocusAreas إلى ActivityView
، وهو جذور التدرج الهرمي لطريقة العرض في
يُعدّ ActivityView
أحد مجالات التركيز الضمني.
الأزرار التي تعمل عند الضغط مع الاستمرار
تؤدي معظم الأزرار إلى تنفيذ بعض الإجراءات عند النقر عليها. تعمل بعض الأزرار عند الضغط مع الاستمرار بدلاً من ذلك.
على سبيل المثال، عادةً ما يعمل زرا التقديم السريع و الترجيع عند الضغط مع الاستمرار. لإجراء ذلك
أزرار دعم الدوران، الاستماع إلى KEYCODE_DPAD_CENTER
KeyEvents
على النحو التالي:
mButton.setOnKeyListener((v, keyCode, event) -> { if (keyCode != KEYCODE_DPAD_CENTER) { return false; } if (event.getAction() == ACTION_DOWN) { mButton.setPressed(true); mHandler.post(mRunnable); } else { mButton.setPressed(false); mHandler.removeCallbacks(mRunnable); } return true; });
يتم من خلاله اتخاذ إجراء من قِبل "mRunnable
" (مثل ترجيع الفيديو) وتحديد موعد عرضه
أن يتم تنفيذها بعد تأخير.
وضع اللمس
يمكن للمستخدمين استخدام وحدة تحكم دوّارة للتفاعل مع الوحدة الرئيسية في السيارة بطريقتين، إما باستخدام وحدة التحكم الدوارة أو عن طريق لمس الشاشة. عند استخدام وحدة التحكم الدوارة، حيث يتم تمييز إحدى طرق العرض التي يمكن التركيز عليها. لا يتم تمييز التركيز عند لمس الشاشة. تظهر. يمكن للمستخدم التبديل بين أوضاع الإدخال التالية في أي وقت:
- مفتاح دوران → لمسة عندما يلمس المستخدم الشاشة، يختفي تمييز التركيز.
- انقر على ← زر دوار. عندما يضغط المستخدم على زر "المركز" أو يحرّكه أو يضغط عليه، فإن يظهر تمييز التركيز.
ولا يكون لزرَي الرجوع والصفحة الرئيسية أي تأثير في وضع الإدخال.
العلامات المترابطة الدوارة حول المفهوم الحالي لنظام Android
وضع اللمس.
يمكنك استخدام
View.isInTouchMode()
لتحديد وضع الإدخال الذي يستخدمه المستخدم. يمكنك استخدام
OnTouchModeChangeListener
من الاستماع إلى التغييرات. وعلى الرغم من إمكانية استخدامه لتخصيص واجهة المستخدم الحالية،
وضع الإدخال، تجنب أي تغييرات كبيرة لأنها قد تكون مربكة.
تحديد المشاكل وحلّها
في تطبيق مصمم للمس، من الشائع أن يكون هناك طرق عرض متداخلة يمكن التركيز عليها.
على سبيل المثال، قد يكون هناك FrameLayout
حول ImageButton
،
وكلاهما يمكن التركيز عليه. لا يضر هذا اللمس، ولكن يمكن أن يؤدي إلى
تجربة المستخدم للدوران لأن المستخدم يجب أن يقوم بتدوير وحدة التحكم مرتين للانتقال إلى
العرض التفاعلي التالي. لتقديم تجربة جيدة للمستخدمين، تنصحك Google بإجراء أيّ مما يلي:
يمكن التركيز على العرض الخارجي أو الرؤية الداخلية، ولكن ليس كليهما.
إذا فقد أحد الأزرار أو المفاتيح التركيز عند الضغط على وحدة التحكم الدوارة، فإن أحد قد تنطبق هذه الشروط:
- يتم إيقاف الزر أو مفتاح التحكّم (لفترة قصيرة أو إلى أجل غير مسمى) بسبب
عند الضغط عليها. في كلتا الحالتين، هناك طريقتان لمعالجة هذا الأمر:
- ترك حالة
android:enabled
علىtrue
واستخدام حالة مخصصة التبديل إلى اللون الرمادي للزر أو التبديل كما هو موضح في الحالة المخصَّصة: - استخدِم حاوية لإحاطة الزر أو مفتاح التحكّم وجعل الحاوية قابلة للتركيز بدلاً من الزر أو المفتاح. (يجب أن يكون مستمع النقر في الحاوية.)
- ترك حالة
- يتم استبدال الزر أو مفتاح التحكّم. على سبيل المثال، الإجراء الذي يتم اتخاذه عند النقر على الزر
قد يؤدي الضغط على مفتاح التبديل أو تفعيل مفتاح التبديل إلى إعادة تحميل الإجراءات المتاحة
مما يتسبب في استبدال الأزرار الجديدة بالأزرار الموجودة. هناك طريقتان لمعالجة هذا الأمر:
- وبدلاً من إنشاء زر أو مفتاح جديد، يمكنك تعيين رمز و/أو نص الزر أو مفتاح التبديل الحالي.
- كما هو موضح أعلاه، أضِف حاوية يمكن التركيز عليها حول الزر أو مفتاح التحكّم.
ملعب دوّار
"RotaryPlayground
" هو تطبيق مرجعي لنظام التشغيل الدوّار. يمكنك استخدامه لمعرفة كيفية دمج
الميزات الدورية في تطبيقاتك. تم تضمين RotaryPlayground
في إصدارات المحاكي وفي
للإصدارات المخصصة للأجهزة التي تعمل بنظام التشغيل Android Automotive (AAOS).
- مستودع واحد (
RotaryPlayground
):packages/apps/Car/tests/RotaryPlayground/
- الإصدارات: Android 11 QPR3، Android 11 Car، وAndroid 12
يعرض تطبيق "RotaryPlayground
" علامات التبويب التالية على اليمين:
- البطاقات: اختبار التنقل حول مناطق التركيز، وتخطي العناصر غير القابلة للتركيز وإدخال النص.
- التلاعب المباشر: اختبار التطبيقات المصغّرة التي تتوافق مع التطبيقات البسيطة والمتقدّمة أسلوب التحكم المباشر. علامة التبويب هذه مخصصة للتلاعب المباشر داخل نافذة التطبيق.
- معالجة واجهة مستخدم النظام (Sys) اختبار التطبيقات المصغّرة التي تتيح التحكّم المباشر في نوافذ النظام التي يتوفر فيها وضع التلاعب المباشر البسيط فقط.
- "الشبكة": اختبِر التنقّل الدوّار على شكل حرف z من خلال التمرير.
- الإشعار. يمكنك اختبار ميزة الدفع من داخل الإشعارات المُرسَلة وخارجها.
- التمرير اختبار التنقّل بين عناصر يمكن التركيز عليها وتلك التي لا يمكن التركيز عليها المحتوى.
- WebView: اختبار التنقّل بين الروابط في
WebView
- مخصّص
FocusArea
. اختبار تخصيصFocusArea
:- التفاف.
android:focusedByDefault
وapp:defaultFocus
.
- أهداف التذكير التلقائي الصريح
- تذكير تلقائي بالاختصارات.
FocusArea
بدون أي مشاهدات يمكن التركيز عليها