مطالب زیر برای توسعه دهندگان برنامه است.
برای اینکه برنامه خود را به صورت چرخشی پشتیبانی کنید، باید:
- یک
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
استفاده کنید.
برای دسترسی به کنترلر چرخشی شبیه سازی شده:
- روی سه نقطه در پایین نوار ابزار ضربه بزنید:
شکل 1. به کنترل کننده چرخشی شبیه سازی شده دسترسی پیدا کنید - در پنجره کنترلهای توسعهیافته Car rotary را انتخاب کنید:
شکل 2. Car rotary را انتخاب کنید
صفحه کلید USB
- یک صفحه کلید USB را به دستگاه خود وصل کنید که دارای سیستم عامل Android Automotive (AAOS) است، در برخی موارد، این کار از نمایش صفحه کلید روی صفحه جلوگیری می کند.
- از یک
userdebug
یاeng
build استفاده کنید. - فعال کردن فیلتر رویداد کلیدی:
adb shell settings put secure android.car.ROTARY_KEY_EVENT_FILTER 1
- برای یافتن کلید مربوطه برای هر عمل به جدول زیر مراجعه کنید:
کلید عمل چرخشی س در خلاف جهت عقربه های ساعت بچرخانید E در جهت عقربه های ساعت بچرخانید الف به چپ تکان دهید D به سمت راست تکان دهید دبلیو تلنگر بزنید اس به پایین تلنگر بزنید 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 | دکمه برگشت را کلیک کنید |
کنترل کننده چرخشی OEM
هنگامی که سخت افزار کنترلر چرخشی شما آماده و در حال اجرا است، این واقعی ترین گزینه است. این به ویژه برای تست چرخش سریع مفید است.
FocusParkingView
FocusParkingView
یک نمای شفاف در کتابخانه UI Car (car-ui-library) است. RotaryService
از آن برای پشتیبانی از ناوبری کنترلر چرخشی استفاده می کند. FocusParkingView
باید اولین نمای قابل فوکوس در طرح باشد. باید خارج از همه FocusArea
قرار گیرد. هر پنجره باید یک FocusParkingView
داشته باشد. اگر قبلاً از طرحبندی پایه car-ui-library که حاوی 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 به طور خودکار فوکوس را پاک نمی کند. اگر سعی کنید فوکوس را در پنجره قبلی پاک کنید، اندروید نمای آن پنجره را مجدداً فوکوس میکند که منجر به فوکوس شدن همزمان دو پنجره میشود. افزودن
FocusParkingView
به هر پنجره می تواند این مشکل را برطرف کند. این نما شفاف است و برجسته کردن فوکوس پیشفرض آن غیرفعال است، به طوری که بدون توجه به فوکوس یا عدم تمرکز، برای کاربر نامرئی است. می تواند فوکوس را بگیرد تاRotaryService
بتواند فوکوس را روی آن پارک کند تا برجسته شدن فوکوس حذف شود. - اگر فقط یک
FocusArea
در پنجره فعلی وجود داشته باشد، چرخاندن کنترلر درFocusArea
باعث می شود تاRotaryService
فوکوس را از نمای سمت راست به نمای سمت چپ (و بالعکس) منتقل کند. افزودن این نما به هر پنجره می تواند مشکل را برطرف کند. هنگامی کهRotaryService
تعیین می کند که هدف فوکوس یکFocusParkingView
است، می تواند تعیین کند که یک wrap-around در شرف وقوع است که در آن نقطه با عدم حرکت فوکوس از چرخش دور جلوگیری می کند. - هنگامی که کنترل چرخشی یک برنامه را راه اندازی می کند، Android اولین نمای قابل فوکوس را متمرکز می کند که همیشه
FocusParkingView
است.FocusParkingView
نمای بهینه برای فوکوس را تعیین می کند و سپس فوکوس را اعمال می کند.
نماهای قابل تمرکز
RotaryService
مبتنی بر مفهوم موجود چارچوب Android از تمرکز دید است که به زمانی برمی گردد که تلفن ها دارای صفحه کلید فیزیکی و D-pad بودند. ویژگی android:nextFocusForward
موجود برای چرخشی تغییر کاربری داده شده است (به سفارشی سازی FocusArea مراجعه کنید)، اما android:nextFocusLeft
، android:nextFocusRight
، android:nextFocusUp
و android:nextFocusDown
اینگونه نیستند.
RotaryService
فقط بر روی نماهایی تمرکز می کند که قابل فوکوس هستند. برخی از نماها، مانند Button
s، معمولاً قابل فوکوس هستند. سایرین، مانند TextView
s و ViewGroup
s، معمولاً اینطور نیستند. نماهای قابل کلیک به طور خودکار قابل فوکوس هستند و نماها زمانی که شنونده کلیک داشته باشند به طور خودکار قابل کلیک هستند. اگر این منطق خودکار منجر به فوکوس پذیری مورد نظر می شود، نیازی نیست به صراحت قابلیت فوکوس پذیری نما را تنظیم کنید. اگر منطق خودکار به فوکوسپذیری مورد نظر منجر نمیشود، ویژگی android:focusable
روی true
یا false
تنظیم کنید، یا با برنامه View.setFocusable(boolean)
قابلیت تمرکز نمای را تنظیم کنید. برای اینکه RotaryService
روی آن تمرکز کند، یک View باید شرایط زیر را داشته باشد:
- قابل تمرکز
- فعال شد
- قابل مشاهده است
- مقادیر غیر صفر برای عرض و ارتفاع داشته باشید
اگر یک نما تمام این الزامات را برآورده نکند، برای مثال یک دکمه قابل فوکوس اما غیرفعال، کاربر نمی تواند از کنترل چرخشی برای فوکوس روی آن استفاده کند. اگر میخواهید روی نماهای غیرفعال تمرکز کنید، به جای 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);
- در کلاس view خود، متد
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; }
- کاری کنید که کنترل کننده کلیک نمای شما بسته به وضعیت آن عملکرد متفاوتی داشته باشد. به عنوان مثال، کنترل کننده کلیک ممکن است کاری انجام ندهد یا زمانی که
mRotaryEnabled
false
است، یک نان تست ظاهر شود. - برای اینکه دکمه غیرفعال به نظر برسد، در پسزمینه نمای خود، به جای
android:state_enabled
app:state_rotary_enabled
:state_rotary_enabled استفاده کنید. اگر قبلاً آن را ندارید، باید اضافه کنید:xmlns:app="http://schemas.android.com/apk/res-auto"
- اگر نمای شما در هر طرحبندی غیرفعال است،
android:enabled="false"
باapp:state_rotary_enabled="false"
جایگزین کنید و سپس فضای نامapp
را مانند بالا اضافه کنید. - اگر نمای شما از نظر برنامهنویسی غیرفعال است، تماسهای
setEnabled()
را با تماسsetRotaryEnabled()
جایگزین کنید.
Focus Area
از FocusAreas
برای تقسیم نماهای قابل تمرکز به بلوکها استفاده کنید تا پیمایش آسانتر شود و با سایر برنامهها سازگار باشد. به عنوان مثال، اگر برنامه شما دارای یک نوار ابزار است، نوار ابزار باید در یک FocusArea
مجزا از بقیه برنامه شما باشد. نوارهای برگه و سایر عناصر ناوبری نیز باید از بقیه برنامه جدا شوند. فهرستهای بزرگ معمولاً باید FocusArea
خاص خود را داشته باشند. در غیر این صورت، کاربران باید در کل لیست بچرخند تا به برخی از نماها دسترسی داشته باشند.
FocusArea
یک زیر کلاس از LinearLayout
در car-ui-library است. هنگامی که این ویژگی فعال است، 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
در سلسله مراتب view می گردد. - هنگام دریافت یک رویداد چرخشی،
RotaryService
فوکوس را به نمای دیگری منتقل می کند که می تواند در همانFocusArea
تمرکز کند. - هنگام دریافت یک رویداد نوج،
RotaryService
فوکوس را به نمای دیگری منتقل می کند که می تواند درFocusArea
دیگر (معمولاً مجاور) تمرکز کند.
اگر هیچ FocusAreas
در طرح بندی خود وارد نکنید، نمای ریشه به عنوان یک ناحیه تمرکز ضمنی در نظر گرفته می شود. کاربر نمی تواند برای پیمایش در برنامه تلنگر بزند. در عوض، آنها از طریق تمام نمای های قابل فوکوس می چرخند، که ممکن است برای گفتگوها کافی باشد.
سفارشی سازی FocusArea
برای سفارشی کردن ناوبری چرخشی می توان از دو ویژگی View استاندارد استفاده کرد:
-
android:nextFocusForward
به توسعه دهندگان برنامه اجازه می دهد تا ترتیب چرخش را در یک ناحیه فوکوس مشخص کنند. این همان مشخصه ای است که برای کنترل ترتیب Tab برای پیمایش صفحه کلید استفاده می شود. از این ویژگی برای ایجاد یک حلقه استفاده نکنید . در عوض، ازapp:wrapAround
(به زیر مراجعه کنید) برای ایجاد یک حلقه استفاده کنید. -
android:focusedByDefault
به توسعه دهندگان برنامه اجازه می دهد نمای فوکوس پیش فرض را در پنجره مشخص کنند. از این ویژگی وapp:defaultFocus
(به زیر مراجعه کنید) در همانFocusArea
استفاده نکنید .
FocusArea
همچنین برخی از ویژگی ها را برای سفارشی کردن ناوبری چرخشی تعریف می کند. مناطق فوکوس ضمنی را نمی توان با این ویژگی ها سفارشی کرد.
- ( اندروید 11 QPR3، اندروید 11 ماشین، اندروید 12 )
app:defaultFocus
می توان برای تعیین شناسه نمای اصلی قابل فوکوس استفاده کرد، که وقتی کاربر به اینFocusArea
اشاره می کند باید روی آن متمرکز شود. - ( اندروید 11 QPR3، اندروید 11 ماشین، اندروید 12 )
app:defaultFocusOverridesHistory
می توان رویtrue
تنظیم کرد تا نمای مشخص شده در بالا تمرکز داشته باشد، حتی اگر با تاریخچه نشان دهد نمای دیگری در اینFocusArea
روی آن متمرکز شده بود. - ( اندروید 12 )
ازapp:nudgeLeftShortcut
،app:nudgeRightShortcut
،app:nudgeUpShortcut
، وapp:nudgeDownShortcut
برای تعیین شناسه نمای اصلی قابل فوکوس استفاده کنید، که وقتی کاربر در جهت معینی حرکت میکند باید روی آن متمرکز شود. برای کسب اطلاعات بیشتر، به محتوای میانبرهای نوج زیر مراجعه کنید.( Android 11 QPR3، Android 11 Car، در Android 12 منسوخ شده است )
app:nudgeShortcut
وapp:nudgeShortcutDirection
تنها از یک میانبر nudge پشتیبانی می کنند. - ( اندروید 11 QPR3، اندروید 11 ماشین، اندروید 12 )
برای فعال کردن چرخش در اینFocusArea
،app:wrapAround
می توان رویtrue
تنظیم کرد. این معمولاً زمانی استفاده می شود که نماها در یک دایره یا بیضی مرتب شده باشند. - ( اندروید 11 QPR3، اندروید 11 ماشین، اندروید 12 )
برای تنظیم لایه هایلایت در اینFocusArea
،app:highlightPaddingStart
،app:highlightPaddingEnd
،app:highlightPaddingTop
،app:highlightPaddingBottom
،app:highlightPaddingHorizontal
وapp:highlightPaddingVertical
استفاده کنید. - ( اندروید 11 QPR3، اندروید 11 ماشین، اندروید 12 )
برای تنظیم مرزهای درک شده اینFocusArea
برای یافتن یک هدف حرکتی،app:startBoundOffset
،app:endBoundOffset
،app:topBoundOffset
،app:bottomBoundOffset
،app:horizontalBoundOffset
، وapp:verticalBoundOffset
استفاده کنید. - ( اندروید 11 QPR3، اندروید 11 ماشین، اندروید 12 )
برای مشخص کردن صریح شناسه یکFocusArea
(یا مناطق) مجاور در جهتهای داده شده،app:nudgeLeft
،app:nudgeRight
،app:nudgeUp
وapp:nudgeDown
استفاده کنید. وقتی جستجوی هندسی که به طور پیشفرض استفاده میشود، هدف مورد نظر را پیدا نمیکند، از این استفاده کنید.
Nudging معمولاً بین Focus Areas حرکت می کند. اما با میانبرهای اشارهای، گاهی اوقات حرکت دادن ابتدا در یک FocusArea
حرکت میکند، به طوری که کاربر ممکن است برای پیمایش به FocusArea
بعدی نیاز داشته باشد دو بار ضربه بزند. میانبرهای Nudge زمانی مفید هستند که یک FocusArea
شامل یک لیست طولانی و به دنبال آن یک دکمه عمل شناور باشد، مانند مثال زیر:

بدون میانبر nudge، کاربر باید در کل لیست بچرخد تا به FAB برسد.
سفارشی سازی برجسته فوکوس
همانطور که در بالا ذکر شد، RotaryService
بر اساس مفهوم موجود در چارچوب Android از تمرکز دیدگاه است. هنگامی که کاربر میچرخد و حرکت میدهد، RotaryService
فوکوس را به اطراف منتقل میکند، یک نمای را فوکوس میکند و دیگری را از حالت فوکوس خارج میکند. در اندروید، وقتی یک نما فوکوس میشود، اگر نمای:
- برجسته تمرکز خود را مشخص کرده است، آندروید برجسته فوکوس نمای را می کشد.
- برجستهسازی فوکوس را مشخص نمیکند، و برجستهسازی پیشفرض فوکوس غیرفعال نیست، اندروید برجستهسازی فوکوس پیشفرض را برای نما ترسیم میکند.
برنامه هایی که برای لمس طراحی شده اند معمولاً نقاط برجسته فوکوس مناسب را مشخص نمی کنند.
برجستهسازی پیشفرض فوکوس توسط چارچوب Android ارائه میشود و میتواند توسط OEM لغو شود. توسعه دهندگان برنامه زمانی آن را دریافت می کنند که طرح زمینه ای که استفاده می کنند از Theme.DeviceDefault
مشتق شده باشد.
برای تجربه کاربری ثابت، هر زمان که ممکن است به برجسته کردن فوکوس پیشفرض تکیه کنید. اگر به برجستهسازی فوکوس سفارشی (مثلاً گرد یا قرصی) نیاز دارید، یا اگر از تمی استفاده میکنید که از Theme.DeviceDefault
مشتق نشده است، از منابع car-ui-library برای مشخص کردن برجستهسازی فوکوس خود برای هر نما استفاده کنید.
برای تعیین برجستهسازی فوکوس سفارشی برای یک نما، پسزمینه یا پیشزمینه قابل ترسیم نما را به قابل ترسیمی تغییر دهید که وقتی نما روی آن فوکوس میشود، متفاوت باشد. به طور معمول، شما پس زمینه را تغییر می دهید. ترسیم زیر، اگر به عنوان پسزمینه برای نمای مربعی استفاده شود، برجسته فوکوس گرد ایجاد میکند:
<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 ) منابع پررنگ در نمونه بالا منابع تعریف شده توسط car-ui-library را شناسایی می کند. OEM این موارد را لغو می کند تا با برجسته سازی پیش فرضی که مشخص می کنند مطابقت داشته باشد. این تضمین میکند که وقتی کاربر بین یک نمای با برجستهسازی فوکوس سفارشی و یک نمای با برجستهسازی فوکوس پیشفرض حرکت میکند، رنگ برجسته فوکوس، عرض ضربه و غیره تغییر نمیکند. آخرین مورد یک ریپل است که برای لمس استفاده می شود. مقادیر پیش فرض استفاده شده برای منابع پررنگ به صورت زیر ظاهر می شوند:

علاوه بر این، هنگامی که به دکمهای رنگ پسزمینه ثابت داده میشود تا توجه کاربر را جلب کند، برجستهسازی فوکوس سفارشی فراخوانی میشود، مانند مثال زیر. این می تواند برجسته شدن فوکوس را دشوار کند. در این شرایط، با استفاده از رنگ های ثانویه ، یک برجسته فوکوس سفارشی را مشخص کنید:
![]() |
- ( اندروید 11 QPR3، اندروید 11 ماشین، اندروید 12 )
car_ui_rotary_focus_fill_secondary_color
car_ui_rotary_focus_stroke_secondary_color
- ( اندروید 12 )
car_ui_rotary_focus_pressed_fill_secondary_color
car_ui_rotary_focus_pressed_stroke_secondary_color
به عنوان مثال:
![]() | ![]() | |
متمرکز، نه تحت فشار | متمرکز، فشرده |
پیمایش چرخشی
اگر برنامه شما از RecyclerView
s استفاده می کند، باید به جای آن از CarUiRecyclerView
استفاده کنید. این تضمین میکند که UI شما با دیگران سازگار است، زیرا سفارشیسازی OEM برای همه CarUiRecyclerView
اعمال میشود.
اگر عناصر موجود در لیست شما همه قابل تمرکز هستند، لازم نیست کار دیگری انجام دهید. پیمایش چرخشی، فوکوس را از میان عناصر موجود در لیست حرکت میدهد و فهرست برای نمایان شدن عنصر تازه فوکوسشده، پیمایش میکند.
( اندروید 11 QPR3، اندروید 11 ماشین، اندروید 12 )
اگر ترکیبی از عناصر قابل فوکوس و غیرقابل تمرکز وجود دارد، یا اگر همه عناصر غیرقابل تمرکز هستند، میتوانید پیمایش چرخشی را فعال کنید، که به کاربر اجازه میدهد از کنترلکننده چرخشی استفاده کند تا به تدریج در لیست بدون رد شدن از موارد غیرقابل تمرکز حرکت کند. برای فعال کردن پیمایش چرخشی، ویژگی app:rotaryScrollEnabled
را روی true
تنظیم کنید.
( اندروید 11 QPR3، اندروید 11 ماشین، اندروید 12 )
میتوانید اسکرول چرخشی را در هر نمای قابل پیمایش، از جمله av CarUiRecyclerView
، با متد setRotaryScrollEnabled()
در CarUiUtils
فعال کنید. اگر این کار را انجام دهید، باید:
- نمای پیمایشی را قابل فوکوس کنید تا زمانی که هیچ یک از نماهای اصلی قابل فوکوس قابل مشاهده نیست، روی آن فوکوس شود.
- با فراخوانی
setDefaultFocusHighlightEnabled(false)
برجسته کردن فوکوس پیشفرض در نمای قابل پیمایش را غیرفعال کنید تا نمای قابل پیمایش متمرکز به نظر نرسد. - با فراخوانی
setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS)
اطمینان حاصل کنید که نمای قابل پیمایش قبل از فرزندان خود متمرکز شده است. - با
SOURCE_ROTARY_ENCODER
وAXIS_VSCROLL
یاAXIS_HSCROLL
به MotionEvents گوش دهید تا فاصله پیمایش و جهت را (از طریق علامت) نشان دهید.
هنگامی که پیمایش چرخشی در CarUiRecyclerView
فعال میشود و کاربر به ناحیهای میچرخد که در آن هیچ نمای قابل تمرکزی وجود ندارد، نوار اسکرول از خاکستری به آبی تغییر میکند، گویی که نشان میدهد نوار اسکرول فوکوس شده است. اگر دوست دارید می توانید یک افکت مشابه را پیاده سازی کنید.
MotionEvents مانند مواردی است که توسط چرخ اسکرول روی ماوس ایجاد می شود، به جز منبع.
حالت دستکاری مستقیم
به طور معمول، تکان دادن و چرخش در رابط کاربری حرکت می کند، در حالی که دکمه مرکزی را فشار می دهد، هر چند همیشه اینطور نیست. به عنوان مثال، اگر کاربری بخواهد صدای زنگ هشدار را تنظیم کند، ممکن است از کنترلر چرخشی برای حرکت به نوار لغزنده صدا استفاده کند، دکمه مرکز را فشار دهد، کنترلر را بچرخاند تا صدای زنگ هشدار را تنظیم کند، و سپس دکمه برگشت را برای بازگشت به مسیریابی فشار دهد. به این حالت دستکاری مستقیم (DM) می گویند. در این حالت، کنترلر چرخشی برای تعامل مستقیم با نما به جای جهت یابی استفاده می شود.
DM را به یکی از دو روش پیاده سازی کنید. اگر فقط باید چرخش را مدیریت کنید و نمای مورد نظر برای دستکاری به ACTION_SCROLL_FORWARD
و ACTION_SCROLL_BACKWARD
AccessibilityEvent
به طور مناسب پاسخ می دهد، از مکانیسم ساده استفاده کنید. در غیر این صورت از مکانیزم پیشرفته استفاده کنید.
مکانیسم ساده تنها گزینه در ویندوز سیستم است. برنامه ها می توانند از هر مکانیزم استفاده کنند.
مکانیزم ساده
( اندروید 11 QPR3، اندروید 11 ماشین، اندروید 12 )
برنامه شما باید DirectManipulationHelper.setSupportsRotateDirectly(View view, boolean enable)
را فراخوانی کند. RotaryService
تشخیص می دهد که کاربر در حالت DM است و هنگامی که کاربر دکمه مرکز را فشار می دهد در حالی که یک نما فوکوس شده است وارد حالت DM می شود. در حالت DM، چرخشها ACTION_SCROLL_FORWARD
یا ACTION_SCROLL_BACKWARD
را انجام میدهند و وقتی کاربر دکمه برگشت را فشار میدهد از حالت DM خارج میشود. مکانیسم ساده حالت انتخاب شده نما را هنگام ورود و خروج از حالت DM تغییر می دهد.
برای ارائه یک نشانه بصری مبنی بر اینکه کاربر در حالت DM است، هنگام انتخاب نمای خود را متفاوت نشان دهید. برای مثال، زمانی که android:state_selected
true
است، پسزمینه را تغییر دهید.
مکانیزم پیشرفته
برنامه تعیین میکند که RotaryService
چه زمانی وارد حالت DM شود و از آن خارج شود. برای تجربه کاربری ثابت، فشار دادن دکمه مرکز با نمای DM متمرکز باید وارد حالت DM شود و دکمه برگشت باید از حالت DM خارج شود. اگر از دکمه مرکزی و/یا تلنگر استفاده نمیشود، میتوانند راههای جایگزینی برای خروج از حالت DM باشند. برای برنامه هایی مانند Maps، می توان از دکمه ای برای نشان دادن DM برای ورود به حالت DM استفاده کرد.
برای پشتیبانی از حالت DM پیشرفته، یک نما:
- ( Android 11 QPR3, Android 11 Car, Android 12 ) برای ورود به حالت DM باید به رویداد
KEYCODE_DPAD_CENTER
گوش دهید و برای خروج از حالت DM به رویدادKEYCODE_BACK
گوش دهید و در هر موردDirectManipulationHelper.enableDirectManipulationMode()
را فراخوانی کنید. برای گوش دادن به این رویدادها، یکی از موارد زیر را انجام دهید:- یک
OnKeyListener
ثبت کنید. یا، - View را گسترش دهید و سپس متد
dispatchKeyEvent()
آن را لغو کنید.
- یک
- اگر نما باید با تلنگرها برخورد کند، باید به رویدادهای نوج گوش دهید (
KEYCODE_DPAD_UP
،KEYCODE_DPAD_DOWN
،KEYCODE_DPAD_LEFT
، یاKEYCODE_DPAD_RIGHT
). - اگر نمای میخواهد چرخش را مدیریت کند، باید به
MotionEvent
گوش دهید و تعداد چرخش را درAXIS_SCROLL
دریافت کنید. چندین راه برای این کار وجود دارد:- یک
OnGenericMotionListener
ثبت کنید. - نمایش را گسترش دهید و متد
dispatchTouchEvent()
آن را لغو کنید.
- یک
- برای جلوگیری از گیر افتادن در حالت DM، باید از حالت DM خارج شوید زمانی که بخش یا فعالیتی که نمای به آن تعلق دارد تعاملی نیست.
- باید یک نشانه بصری برای نشان دادن اینکه نما در حالت DM است ارائه دهد.
نمونه ای از نمای سفارشی که از حالت 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:
-
ActivityView
نباید قابل تمرکز باشد. - ( Android 11 QPR3، Android 11 Car، منسوخ شده در Android 11 )
محتویاتActivityView
باید حاویFocusParkingView
به عنوان اولین نمای قابل فوکوس باشد و ویژگیapp:shouldRestoreFocus
بایدfalse
باشد. - محتویات
ActivityView
نباید نماهایandroid:focusByDefault
داشته باشند.
برای کاربر، ActivityViews نباید هیچ تأثیری در مسیریابی داشته باشد، به جز اینکه مناطق فوکوس نمی توانند ActivityViews را پوشش دهند. به عبارت دیگر، نمیتوانید یک ناحیه فوکوس واحد داشته باشید که دارای محتوای داخل و خارج از ActivityView
باشد. اگر هیچ FocusAreas را به ActivityView
خود اضافه نکنید، ریشه سلسله مراتب view در ActivityView
یک ناحیه تمرکز ضمنی در نظر گرفته می شود.
دکمه هایی که با نگه داشتن آن عمل می کنند
اکثر دکمهها هنگام کلیک کردن باعث ایجاد برخی عملکردها میشوند. در عوض برخی از دکمه ها با نگه داشتن آن کار می کنند. به عنوان مثال، دکمههای Fast Forward و Rewind معمولاً زمانی کار میکنند که پایین نگه داشته میشوند. برای اینکه چنین دکمههایی از چرخش پشتیبانی کنند، به 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
عملی را انجام می دهد (مثلاً به عقب) و برنامه ریزی می کند تا پس از تأخیر اجرا شود.
حالت لمسی
کاربران می توانند از یک کنترلر چرخشی برای تعامل با هد یونیت در خودرو به دو روش استفاده کنند، یا با استفاده از کنترلر چرخشی یا با لمس صفحه نمایش. هنگام استفاده از کنترلر چرخشی، یکی از نماهای قابل فوکوس برجسته می شود. هنگام لمس صفحه، هیچ برجسته فوکوس ظاهر نمی شود. کاربر می تواند در هر زمانی بین این حالت های ورودی جابجا شود:
- چرخشی ← لمسی. هنگامی که کاربر صفحه را لمس می کند، برجسته شدن فوکوس ناپدید می شود.
- ← چرخشی را لمس کنید. هنگامی که کاربر دکمه مرکزی را تکان می دهد، می چرخد یا فشار می دهد، برجسته شدن فوکوس ظاهر می شود.
دکمه های Back و Home هیچ تاثیری روی حالت ورودی ندارند.
Piggybacks چرخشی در مفهوم موجود اندروید از حالت لمسی . می توانید از View.isInTouchMode()
استفاده کنید تا مشخص کنید کاربر از کدام حالت ورودی استفاده می کند. برای گوش دادن به تغییرات می توانید از OnTouchModeChangeListener
استفاده کنید. در حالی که این می تواند برای سفارشی کردن رابط کاربری شما برای حالت ورودی فعلی استفاده شود، از هر گونه تغییر عمده اجتناب کنید زیرا ممکن است نگران کننده باشد.
عیب یابی
در اپلیکیشنی که برای لمس طراحی شده است، داشتن نماهای قابل فوکوس تودرتو معمول است. برای مثال، ممکن است یک FrameLayout
در اطراف یک ImageButton
وجود داشته باشد که هر دو قابل فوکوس هستند. این برای لمس ضرری ندارد اما می تواند منجر به تجربه کاربری ضعیف برای چرخش شود زیرا کاربر باید کنترلر را دو بار بچرخاند تا به نمای تعاملی بعدی برود. برای یک تجربه کاربری خوب، گوگل توصیه می کند که نمای بیرونی یا نمای داخلی را قابل فوکوس کنید، اما نه هر دو.
اگر یک دکمه یا سوئیچ با فشار دادن از طریق کنترلر چرخشی فوکوس خود را از دست بدهد، ممکن است یکی از این شرایط اعمال شود:
- دکمه یا سوئیچ به دلیل فشار دادن دکمه (به طور خلاصه یا نامحدود) غیرفعال می شود. در هر صورت، دو راه برای رفع این مشکل وجود دارد:
- حالت
android:enabled
راtrue
بگذارید و از یک حالت سفارشی برای خاکستری کردن دکمه یا سوئیچ همانطور که در حالت سفارشی توضیح داده شده است استفاده کنید. - از یک ظرف برای احاطه کردن دکمه یا سوئیچ استفاده کنید و ظرف را به جای دکمه یا سوئیچ قابل فوکوس کنید. (شنونده کلیک باید روی ظرف باشد.)
- حالت
- دکمه یا سوئیچ در حال تعویض است. برای مثال، اقدامی که هنگام فشار دادن دکمه یا جابجایی کلید انجام میشود، ممکن است باعث بهروزرسانی عملکردهای موجود شود و باعث شود دکمههای جدید جایگزین دکمههای موجود شوند. برای رفع این مشکل دو راه وجود دارد:
- به جای ایجاد یک دکمه یا سوئیچ جدید، نماد و/یا متن دکمه یا سوئیچ موجود را تنظیم کنید.
- مانند بالا، یک ظرف قابل فوکوس در اطراف دکمه یا سوئیچ اضافه کنید.
زمین بازی روتاری
RotaryPlayground
یک برنامه مرجع برای چرخش است. از آن برای یادگیری نحوه ادغام ویژگی های چرخشی در برنامه های خود استفاده کنید. RotaryPlayground
در ساختهای شبیهساز و در ساختهای دستگاههایی که سیستمعامل Android Automotive (AAOS) را اجرا میکنند گنجانده شده است.
- مخزن
RotaryPlayground
:packages/apps/Car/tests/RotaryPlayground/
- نسخه ها: Android 11 QPR3، Android 11 Car و Android 12
برنامه RotaryPlayground
برگه های زیر را در سمت چپ نشان می دهد:
- کارت ها پیمایش در مناطق فوکوس، نادیده گرفتن عناصر غیرقابل تمرکز و ورودی متن را آزمایش کنید.
- دستکاری مستقیم ویجت هایی را تست کنید که از حالت دستکاری مستقیم ساده و پیشرفته پشتیبانی می کنند. این تب به طور خاص برای دستکاری مستقیم در پنجره برنامه است.
- دستکاری UI Sys. ویجتهایی را تست کنید که از دستکاری مستقیم در ویندوزهای سیستم پشتیبانی میکنند که در آن فقط حالت دستکاری مستقیم ساده پشتیبانی میشود.
- شبکه ناوبری چرخشی الگوی z را با اسکرول تست کنید.
- اطلاع رسانی اعلانهای هدآپ را تست کنید.
- اسکرول کنید. پیمایش را در ترکیبی از محتوای قابل تمرکز و غیر قابل تمرکز آزمایش کنید.
- WebView. پیمایش از طریق پیوندها را در
WebView
آزمایش کنید. -
FocusArea
سفارشی. تست سفارشی سازیFocusArea
:- بپیچید.
-
android:focusedByDefault
وapp:defaultFocus
. - اهداف تلنگر آشکار
- میانبرهای تلنگر.
-
FocusArea
بدون نماهای قابل فوکوس.
مطالب زیر برای توسعه دهندگان برنامه است.
برای اینکه برنامه خود را به صورت چرخشی پشتیبانی کنید، باید:
- یک
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
استفاده کنید.
برای دسترسی به کنترلر چرخشی شبیه سازی شده:
- روی سه نقطه در پایین نوار ابزار ضربه بزنید:
شکل 1. به کنترل کننده چرخشی شبیه سازی شده دسترسی پیدا کنید - در پنجره کنترلهای توسعهیافته Car rotary را انتخاب کنید:
شکل 2. Car rotary را انتخاب کنید
صفحه کلید USB
- یک صفحه کلید USB را به دستگاه خود وصل کنید که دارای سیستم عامل Android Automotive (AAOS) است، در برخی موارد، این کار از نمایش صفحه کلید روی صفحه جلوگیری می کند.
- از یک
userdebug
یاeng
build استفاده کنید. - فعال کردن فیلتر رویداد کلیدی:
adb shell settings put secure android.car.ROTARY_KEY_EVENT_FILTER 1
- برای یافتن کلید مربوطه برای هر عمل به جدول زیر مراجعه کنید:
کلید عمل چرخشی س در خلاف جهت عقربه های ساعت بچرخانید E در جهت عقربه های ساعت بچرخانید الف به چپ تکان دهید D به سمت راست تکان دهید دبلیو تلنگر بزنید اس به پایین تلنگر بزنید 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 | دکمه برگشت را کلیک کنید |
کنترل کننده چرخشی OEM
هنگامی که سخت افزار کنترلر چرخشی شما آماده و در حال اجرا است، این واقعی ترین گزینه است. این به ویژه برای تست چرخش سریع مفید است.
FocusParkingView
FocusParkingView
یک نمای شفاف در کتابخانه UI Car (car-ui-library) است. RotaryService
از آن برای پشتیبانی از ناوبری کنترلر چرخشی استفاده می کند. FocusParkingView
باید اولین نمای قابل فوکوس در طرح باشد. باید خارج از همه FocusArea
قرار گیرد. هر پنجره باید یک FocusParkingView
داشته باشد. اگر قبلاً از طرحبندی پایه car-ui-library که حاوی 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 به طور خودکار فوکوس را پاک نمی کند. اگر سعی کنید فوکوس را در پنجره قبلی پاک کنید، اندروید نمای آن پنجره را مجدداً فوکوس میکند که منجر به فوکوس شدن همزمان دو پنجره میشود. افزودن
FocusParkingView
به هر پنجره می تواند این مشکل را برطرف کند. این نما شفاف است و برجسته کردن فوکوس پیشفرض آن غیرفعال است، به طوری که بدون توجه به فوکوس یا عدم تمرکز، برای کاربر نامرئی است. می تواند فوکوس را بگیرد تاRotaryService
بتواند فوکوس را روی آن پارک کند تا برجسته شدن فوکوس حذف شود. - اگر فقط یک
FocusArea
در پنجره فعلی وجود داشته باشد، چرخاندن کنترلر درFocusArea
باعث می شود تاRotaryService
فوکوس را از نمای سمت راست به نمای سمت چپ (و بالعکس) منتقل کند. افزودن این نما به هر پنجره می تواند مشکل را برطرف کند. هنگامی کهRotaryService
تعیین می کند که هدف فوکوس یکFocusParkingView
است، می تواند تعیین کند که یک wrap-around در شرف وقوع است که در آن نقطه با عدم حرکت فوکوس از چرخش دور جلوگیری می کند. - هنگامی که کنترل چرخشی یک برنامه را راه اندازی می کند، Android اولین نمای قابل فوکوس را متمرکز می کند که همیشه
FocusParkingView
است.FocusParkingView
نمای بهینه برای فوکوس را تعیین می کند و سپس فوکوس را اعمال می کند.
نماهای قابل تمرکز
RotaryService
مبتنی بر مفهوم موجود چارچوب Android از تمرکز دید است که به زمانی برمی گردد که تلفن ها دارای صفحه کلید فیزیکی و D-pad بودند. ویژگی android:nextFocusForward
موجود برای چرخشی تغییر کاربری داده شده است (به سفارشی سازی FocusArea مراجعه کنید)، اما android:nextFocusLeft
، android:nextFocusRight
، android:nextFocusUp
و android:nextFocusDown
اینگونه نیستند.
RotaryService
فقط بر روی نماهایی تمرکز می کند که قابل فوکوس هستند. برخی از نماها، مانند Button
s، معمولاً قابل فوکوس هستند. سایرین، مانند TextView
s و ViewGroup
s، معمولاً اینطور نیستند. نماهای قابل کلیک به طور خودکار قابل فوکوس هستند و نماها زمانی که شنونده کلیک داشته باشند به طور خودکار قابل کلیک هستند. اگر این منطق خودکار منجر به فوکوس پذیری مورد نظر می شود، نیازی نیست به صراحت قابلیت فوکوس پذیری نما را تنظیم کنید. اگر منطق خودکار به فوکوسپذیری مورد نظر منجر نمیشود، ویژگی android:focusable
روی true
یا false
تنظیم کنید، یا با برنامه View.setFocusable(boolean)
قابلیت تمرکز نمای را تنظیم کنید. برای اینکه RotaryService
روی آن تمرکز کند، یک View باید شرایط زیر را داشته باشد:
- قابل تمرکز
- فعال شد
- قابل مشاهده است
- مقادیر غیر صفر برای عرض و ارتفاع داشته باشید
اگر یک نما تمام این الزامات را برآورده نکند، برای مثال یک دکمه قابل فوکوس اما غیرفعال، کاربر نمی تواند از کنترل چرخشی برای فوکوس روی آن استفاده کند. اگر میخواهید روی نماهای غیرفعال تمرکز کنید، به جای 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);
- در کلاس view خود، متد
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; }
- کاری کنید که کنترل کننده کلیک نمای شما بسته به وضعیت آن عملکرد متفاوتی داشته باشد. به عنوان مثال، کنترل کننده کلیک ممکن است کاری انجام ندهد یا زمانی که
mRotaryEnabled
false
است، یک نان تست ظاهر شود. - برای اینکه دکمه غیرفعال به نظر برسد، در پسزمینه نمای خود، به جای
android:state_enabled
app:state_rotary_enabled
:state_rotary_enabled استفاده کنید. اگر قبلاً آن را ندارید، باید اضافه کنید:xmlns:app="http://schemas.android.com/apk/res-auto"
- اگر نمای شما در هر طرحبندی غیرفعال است،
android:enabled="false"
باapp:state_rotary_enabled="false"
جایگزین کنید و سپس فضای نامapp
را مانند بالا اضافه کنید. - اگر نمای شما از نظر برنامهنویسی غیرفعال است، تماسهای
setEnabled()
را با تماسsetRotaryEnabled()
جایگزین کنید.
Focus Area
از FocusAreas
برای تقسیم نماهای قابل تمرکز به بلوکها استفاده کنید تا پیمایش آسانتر شود و با سایر برنامهها سازگار باشد. به عنوان مثال، اگر برنامه شما دارای یک نوار ابزار است، نوار ابزار باید در یک FocusArea
مجزا از بقیه برنامه شما باشد. نوارهای برگه و سایر عناصر ناوبری نیز باید از بقیه برنامه جدا شوند. فهرستهای بزرگ معمولاً باید FocusArea
خاص خود را داشته باشند. در غیر این صورت، کاربران باید در کل لیست بچرخند تا به برخی از نماها دسترسی داشته باشند.
FocusArea
یک زیر کلاس از LinearLayout
در car-ui-library است. هنگامی که این ویژگی فعال است، 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
در سلسله مراتب view می گردد. - هنگام دریافت یک رویداد چرخشی،
RotaryService
فوکوس را به نمای دیگری منتقل می کند که می تواند در همانFocusArea
تمرکز کند. - هنگام دریافت یک رویداد نوج،
RotaryService
فوکوس را به نمای دیگری منتقل می کند که می تواند درFocusArea
دیگر (معمولاً مجاور) تمرکز کند.
اگر هیچ FocusAreas
در طرح بندی خود وارد نکنید، نمای ریشه به عنوان یک ناحیه تمرکز ضمنی در نظر گرفته می شود. کاربر نمی تواند برای پیمایش در برنامه تلنگر بزند. در عوض، آنها از طریق تمام نمای های قابل فوکوس می چرخند، که ممکن است برای گفتگوها کافی باشد.
سفارشی سازی FocusArea
برای سفارشی سازی ناوبری دوار می توان از دو ویژگی نمای استاندارد استفاده کرد:
-
android:nextFocusForward
به توسعه دهندگان برنامه اجازه می دهد تا ترتیب چرخش را در یک منطقه فوکوس مشخص کنند. این همان ویژگی مورد استفاده برای کنترل ترتیب برگه برای ناوبری صفحه کلید است. برای ایجاد یک حلقه از این ویژگی استفاده نکنید . در عوض ، ازapp:wrapAround
(به زیر مراجعه کنید) برای ایجاد یک حلقه استفاده کنید. -
android:focusedByDefault
به توسعه دهندگان برنامه اجازه می دهد تا نمای فوکوس پیش فرض را در پنجره مشخص کنند. از این ویژگی وapp:defaultFocus
استفاده نکنید : 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
برای مشخص کردن شناسه یک نمای نوادگان قابل توجه ، که باید بر آن متمرکز شود که کاربر در یک جهت معین برهنه شود. برای کسب اطلاعات بیشتر ، محتوای میانبرهای Nudge را در زیر مشاهده کنید.( 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:bottomBoundOffset
app:topBoundOffset
،app:horizontalBoundOffset
،app:verticalBoundOffset
. - ( Android 11 QPR3 ، Android 11 Car ، Android 12 )
برای مشخص کردن صریح شناسه یک مجاورFocusArea
(یا مناطق) در دستورالعمل های داده شده ، ازapp:nudgeLeft
،app:nudgeRight
،app:nudgeUp
وapp:nudgeDown
. از این استفاده کنید وقتی جستجوی هندسی مورد استفاده به طور پیش فرض هدف مورد نظر را پیدا نمی کند.
برهنه معمولاً بین FocusAreas حرکت می کند. اما با میانبرهای ناگفته ، برهنه کردن گاهی اوقات در یک FocusArea
حرکت می کند تا کاربر برای حرکت به FocusArea
بعدی دو بار گول بزند. میانبرهای Nudge مفید هستند که یک FocusArea
شامل یک لیست طولانی است که به دنبال آن یک دکمه عمل شناور است ، مانند مثال زیر:

بدون میانبر Nudge ، کاربر برای رسیدن به FAB مجبور به چرخش در کل لیست می شود.
تمرکز شخصی سازی برجسته
همانطور که در بالا ذکر شد ، RotaryService
بر روی مفهوم موجود Focus View Framework Android ساخته می شود. هنگامی که کاربر می چرخد و می چرخد ، RotaryService
تمرکز را به اطراف می کشاند ، یک نمای را متمرکز می کند و دیگری را تمرکز می کند. در Android ، هنگامی که یک نمای متمرکز است ، در صورت مشاهده:
- Android Focus Focus را برجسته می کند.
- برجسته تمرکز را مشخص نمی کند ، و برجسته پیش فرض Focus غیرفعال نیست ، Android برجسته پیش فرض Focus را برای نمایش ترسیم می کند.
برنامه های طراحی شده برای لمس معمولاً نکات برجسته تمرکز مناسب را مشخص نمی کنند.
برجسته پیش فرض Focus توسط چارچوب Android ارائه شده است و می تواند توسط OEM نادیده گرفته شود. توسعه دهندگان برنامه وقتی موضوعی را که استفاده می کنند از Theme.DeviceDefault
گرفته می شوند ، دریافت می کنند.
برای یک تجربه کاربری سازگار ، هر زمان که ممکن است به برجسته تمرکز پیش فرض تکیه کنید. اگر به یک تمرکز تمرکز به شکل سفارشی (به عنوان مثال ، گرد یا قرص شکل) نیاز دارید ، یا اگر از موضوعی استفاده نمی کنید که از Theme.DeviceDefault
گرفته نشده است. devicedefault ، از منابع Library Car-UI برای مشخص کردن تمرکز خود برای هر نمای استفاده کنید.
برای مشخص کردن یک برجسته تمرکز سفارشی برای یک نمای ، پس زمینه یا پیش زمینه را تغییر دهید و می تواند از منظره به یک نقشه کشیده شود که هنگام تمرکز بر روی آن متفاوت باشد. به طور معمول ، پیش زمینه را تغییر می دهید. کشش زیر ، اگر به عنوان پس زمینه برای یک نمای مربع استفاده شود ، یک تمرکز دور را برجسته می کند:
<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>
. OEM این موارد را با برجسته پیش فرض تمرکز آنها نشان می دهد. این تضمین می کند که تمرکز رنگ ، عرض سکته مغزی ، و غیره تغییر نمی کند وقتی کاربر بین یک نمای با برجسته تمرکز سفارشی و نمای با برجسته تمرکز پیش فرض حرکت می کند. آخرین مورد ، موج دار است که برای لمس استفاده می شود. مقادیر پیش فرض مورد استفاده برای منابع BOLD به شرح زیر است:

علاوه بر این ، هنگامی که یک دکمه به یک رنگ پس زمینه محکم داده می شود ، مانند مثال زیر ، یک برجسته تمرکز سفارشی فراخوانی می شود. این می تواند مشاهده تمرکز را دشوار کند. در این شرایط ، با استفاده از رنگهای ثانویه ، یک تمرکز تمرکز سفارشی را مشخص کنید:
![]() |
- ( 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
s استفاده می کند ، به جای آن باید CarUiRecyclerView
s استفاده کنید. این تضمین می کند که UI شما با دیگران سازگار باشد زیرا سفارشی سازی OEM در مورد همه CarUiRecyclerView
s اعمال می شود.
اگر عناصر موجود در لیست شما همه قابل توجه هستند ، لازم نیست کار دیگری انجام دهید. Navigation Rotary تمرکز را از طریق عناصر موجود در لیست و کتیبه های لیست حرکت می دهد تا عنصر تازه متمرکز قابل مشاهده باشد.
( Android 11 QPR3 ، Android 11 Car ، Android 12 )
اگر ترکیبی از عناصر قابل توجه و غیرقابل تمرکز وجود داشته باشد ، یا اگر همه عناصر قابل توجه نیستند ، می توانید پیمایش چرخشی را فعال کنید ، که به کاربر اجازه می دهد از کنترلر چرخشی استفاده کند تا به تدریج از لیست بدون پرش از موارد غیرقابل تمرکز استفاده کند. برای فعال کردن پیمایش چرخشی ، app:rotaryScrollEnabled
Attribute را بر روی true
.
( Android 11 QPR3 ، Android 11 Car ، Android 12 )
می توانید پیمایش چرخشی را در هر نمای قابل پیمایش ، از جمله AV CarUiRecyclerView
، با روش setRotaryScrollEnabled()
در CarUiUtils
فعال کنید. اگر این کار را انجام دهید ، باید:
- نمای قابل پیمایش را به گونه ای متمرکز کنید که بتواند روی آن متمرکز شود که هیچ یک از دیدگاههای قابل توجه آن قابل مشاهده نباشد ،
- با فراخوانی
setDefaultFocusHighlightEnabled(false)
برجسته پیش فرض Focus را در نمای قابل پیمایش غیرفعال کنید تا نمای قابل پیمایش متمرکز باشد ، - اطمینان حاصل کنید که نمای قابل پیمایش قبل از فرزندان خود با فراخوانی
setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS)
متمرکز شده است. - برای MotionEvents با
SOURCE_ROTARY_ENCODER
و یاAXIS_VSCROLL
یاAXIS_HSCROLL
گوش دهید تا فاصله پیمایش و جهت (از طریق علامت) را نشان دهد.
هنگامی که پیمایش روتاری در یک CarUiRecyclerView
فعال می شود و کاربر به منطقه ای می چرخد که هیچ نمای قابل تمرکز در آن وجود ندارد ، نوار پیمایش از خاکستری به آبی تغییر می کند ، گویی که نشان می دهد نوار پیمایش متمرکز است. در صورت تمایل می توانید یک اثر مشابه را پیاده سازی کنید.
MotionEvents همان مواردی است که توسط یک چرخ پیمایش بر روی موش ایجاد می شود ، به جز منبع.
حالت دستکاری مستقیم
به طور معمول ، Nudges و چرخش از طریق رابط کاربری حرکت می کنند ، در حالی که فشار دکمه های مرکز اقدام می کنند ، هرچند که همیشه اینگونه نیست. به عنوان مثال ، اگر کاربر می خواهد حجم زنگ هشدار را تنظیم کند ، ممکن است از کنترلر چرخشی برای حرکت به کشویی صدا استفاده کند ، دکمه مرکز را فشار دهید ، کنترلر را بچرخانید تا حجم زنگ را تنظیم کند و سپس دکمه عقب را فشار دهید تا به ناوبری برگردد. به این حالت به عنوان حالت دستکاری مستقیم (DM) گفته می شود. در این حالت ، از کنترلر چرخشی برای تعامل مستقیم با نمای و نه حرکت استفاده می شود.
DM را به یکی از دو روش پیاده سازی کنید. اگر فقط نیاز به انجام چرخش و نمای را دارید که می خواهید دستکاری کنید به ACTION_SCROLL_FORWARD
و ACTION_SCROLL_BACKWARD
AccessibilityEvent
مناسب S پاسخ می دهد ، از مکانیسم ساده استفاده کنید. در غیر این صورت ، از مکانیسم پیشرفته استفاده کنید.
مکانیسم ساده تنها گزینه در ویندوز سیستم است. برنامه ها می توانند از هر مکانیزم استفاده کنند.
مکانیسم
( Android 11 QPR3 ، Android 11 Car ، Android 12 )
برنامه شما باید با DirectManipulationHelper.setSupportsRotateDirectly(View view, boolean enable)
. RotaryService
تشخیص می دهد که کاربر در حالت DM قرار دارد و وقتی کاربر دکمه مرکز را فشار می دهد در حالی که یک نمای متمرکز است ، وارد حالت DM می شود. هنگامی که در حالت DM قرار دارد ، چرخش ها ACTION_SCROLL_FORWARD
یا ACTION_SCROLL_BACKWARD
را انجام می دهند و وقتی کاربر دکمه عقب را فشار می دهد ، از حالت DM خارج می شود. مکانیسم ساده هنگام ورود و خروج از حالت DM ، وضعیت انتخاب شده نمای را تغییر می دهد.
برای ارائه نشانه بصری که کاربر در حالت DM قرار دارد ، هنگام انتخاب ، نمای شما متفاوت است. به عنوان مثال ، پس زمینه را تغییر دهید وقتی android:state_selected
true
است.
مکانیسم پیشرفته
برنامه تعیین می کند چه موقع RotaryService
وارد حالت DM می شود. برای یک تجربه کاربری سازگار ، فشار دادن دکمه مرکز با نمای DM Focused باید وارد حالت DM شود و دکمه پشت باید از حالت DM خارج شود. اگر از دکمه مرکز و/یا گنگ استفاده نشود ، می توانند روش های جایگزین برای خروج از حالت DM باشند. برای برنامه هایی مانند نقشه ها ، از یک دکمه برای نشان دادن DM می توان برای وارد کردن حالت DM استفاده کرد.
برای پشتیبانی از حالت پیشرفته DM ، نمای:
- ( Android 11 QPR3 ، Android 11 Car ، Android 12 ) باید یک رویداد
KEYCODE_DPAD_CENTER
گوش دهید تا وارد حالت DM شود و به یک رویدادKEYCODE_BACK
گوش دهید تا از حالت DM خارج شود ، و در هر مورد با نامDirectManipulationHelper.enableDirectManipulationMode()
تماس بگیرید. برای گوش دادن به این رویدادها ، یکی از موارد زیر را انجام دهید:- یک
OnKeyListener
ثبت کنید. یا، - نمای را گسترش داده و سپس روش
dispatchKeyEvent()
خود را نادیده بگیرید.
- یک
- در صورتی که نمای باید از دستگیره ها برخورد کند ، باید به رویدادهای nudge (
KEYCODE_DPAD_UP
،KEYCODE_DPAD_DOWN
،KEYCODE_DPAD_LEFT
یاKEYCODE_DPAD_RIGHT
) گوش فرا دهد. - اگر نمای می خواهد چرخش را کنترل کند ، باید به
MotionEvent
S گوش داده و تعداد چرخش را درAXIS_SCROLL
دریافت کنید. چندین راه برای این کار وجود دارد:- ثبت نام
OnGenericMotionListener
. - نمای را گسترش داده و روش
dispatchTouchEvent()
خود را نادیده بگیرید.
- ثبت نام
- برای جلوگیری از گیر کردن در حالت DM ، باید از حالت DM خارج شوید وقتی قطعه یا فعالیتی که نمای متعلق به آن تعلق دارد تعاملی نیست.
- باید یک نشانه بصری فراهم کند تا نشان دهد نمای در حالت DM است.
نمونه ای از نمای سفارشی که از حالت 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 ، در اندروید 11 کاهش یافته است )
محتوایActivityView
باید به عنوان اولین نمای قابل تمرکز شامل یکFocusParkingView
باشد وapp:shouldRestoreFocus
بایدfalse
باشد. - محتوای
ActivityView
نباید دارایandroid:focusByDefault
بازدید.
برای کاربر ، ActivityViews نباید هیچ تاثیری در ناوبری داشته باشد ، مگر اینکه مناطق تمرکز نمی توانند نمای فعالیت ها را نشان دهند. به عبارت دیگر ، شما نمی توانید یک منطقه تمرکز واحد داشته باشید که محتوای آن در داخل و خارج از یک ActivityView
داشته باشد. اگر هیچ FocusAreas را به ActivityView
خود اضافه نکنید ، ریشه سلسله مراتب نمایش در ActivityView
یک منطقه تمرکز ضمنی محسوب می شود.
دکمه هایی که هنگام نگه داشتن کار می کنند
بیشتر دکمه ها در هنگام کلیک برخی اقدامات را ایجاد می کنند. برخی از دکمه ها هنگام نگه داشتن به جای آن کار می کنند. به عنوان مثال ، دکمه های سریع به جلو و عقب به طور معمول هنگام نگه داشتن کار می کنند. برای ساختن چنین دکمه هایی از چرخش ، از KeyEvents
KEYCODE_DPAD_CENTER
به شرح زیر گوش دهید:
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
اقدامی را انجام می دهد (مانند عقب نشینی) و برنامه ریزی می کند که پس از تأخیر اجرا شود.
حالت لمسی
کاربران می توانند از یک کنترلر چرخشی برای تعامل با واحد سر در یک اتومبیل به دو روش استفاده کنند ، یا با استفاده از کنترلر چرخشی یا با لمس صفحه نمایش. هنگام استفاده از کنترلر چرخشی ، یکی از نماهای قابل توجه برجسته می شود. هنگام لمس کردن صفحه ، هیچ برجسته تمرکز ظاهر نمی شود. کاربر می تواند در هر زمان بین این حالت های ورودی جابجا شود:
- ROTARY → لمس کنید. وقتی کاربر صفحه را لمس می کند ، برجسته تمرکز ناپدید می شود.
- لمس → دوار. هنگامی که کاربر دکمه مرکز را فشار می دهد ، می چرخد یا فشار می دهد ، Focus Highlight ظاهر می شود.
دکمه های پشت و خانگی هیچ تاثیری در حالت ورودی ندارند.
Rotary Piggybacks در مفهوم موجود Android از حالت لمسی . می توانید از View.isInTouchMode()
استفاده کنید تا مشخص کنید که از کدام حالت ورودی کاربر استفاده می کند. برای گوش دادن به تغییرات می توانید از OnTouchModeChangeListener
استفاده کنید. در حالی که این می تواند برای سفارشی کردن رابط کاربری شما برای حالت ورودی فعلی استفاده شود ، از هرگونه تغییر اساسی جلوگیری کنید زیرا می تواند ناامید کننده باشد.
عیب یابی
در برنامه ای که برای Touch طراحی شده است ، معمول است که نماهای قابل توجه را در تو قرار دهید. به عنوان مثال ، ممکن است یک FrameLayout
در اطراف یک ImageButton
وجود داشته باشد ، که هر دو قابل توجه هستند. این هیچ ضرری برای لمس ندارد اما می تواند به یک تجربه کاربر ضعیف برای Rotary منجر شود زیرا کاربر باید دو بار کنترلر را بچرخاند تا به نمای تعاملی بعدی منتقل شود. برای یک تجربه خوب کاربر ، Google توصیه می کند که نمای بیرونی یا نمای داخلی را قابل توجه کنید ، اما هر دو نیست.
اگر یک دکمه یا سوئیچ هنگام فشار دادن از طریق کنترلر چرخشی ، تمرکز خود را از دست بدهد ، ممکن است یکی از این شرایط اعمال شود:
- دکمه یا سوئیچ به دلیل فشار دادن دکمه غیرفعال است (به طور خلاصه یا به طور نامحدود). در هر صورت ، دو روش برای پرداختن به این موضوع وجود دارد:
-
android:enabled
به عنوانtrue
و از یک حالت سفارشی برای خاکستری دکمه یا سوئیچ همانطور که در حالت سفارشی توضیح داده شده است ، استفاده کنید. - برای احاطه دکمه یا سوئیچ از یک ظرف استفاده کنید و به جای دکمه یا سوئیچ ، ظرف را قابل تمرکز کنید. (شنونده کلیک باید روی ظرف باشد.)
-
- دکمه یا سوئیچ در حال تعویض است. به عنوان مثال ، عمل انجام شده هنگام فشار دادن دکمه یا سوئیچ ممکن است باعث تجدید اقدامات موجود شود که باعث می شود دکمه های جدید جایگزین دکمه های موجود شود. برای رفع این مشکل دو راه وجود دارد:
- به جای ایجاد یک دکمه یا سوئیچ جدید ، نماد و/یا متن دکمه موجود یا سوئیچ را تنظیم کنید.
- همانطور که در بالا وجود دارد ، یک ظرف قابل توجه را در اطراف دکمه یا سوئیچ اضافه کنید.
میادین روتاری
RotaryPlayground
یک برنامه مرجع برای Rotary است. از آن برای یادگیری نحوه ادغام ویژگی های Rotary در برنامه های خود استفاده کنید. RotaryPlayground
در ساختارهای شبیه ساز و در ساخت دستگاههایی که سیستم عامل Android Automobile (AAOS) را اجرا می کنند ، گنجانده شده است.
- مخزن
RotaryPlayground
:packages/apps/Car/tests/RotaryPlayground/
- نسخه ها: Android 11 QPR3 ، Android 11 Car و Android 12
برنامه RotaryPlayground
برگه های زیر را در سمت چپ نشان می دهد:
- کارت ها تست پیمایش در مناطق فوکوس ، پرش از عناصر غیرقابل تمرکز و ورودی متن.
- دستکاری مستقیم ابزارک های آزمایشی که از حالت دستکاری مستقیم ساده و پیشرفته پشتیبانی می کنند. این برگه به طور خاص برای دستکاری مستقیم در پنجره برنامه است.
- SYS UI دستکاری. ابزارک های آزمایشی که از دستکاری مستقیم در ویندوز سیستم پشتیبانی می کنند که فقط حالت دستکاری مستقیم ساده پشتیبانی می شود.
- شبکه ناوبری چرخشی Z-Pattern را با پیمایش آزمایش کنید.
- اطلاع رسانی تست برهنه شدن در داخل و خارج از اعلان های سر.
- اسکرول کنید. پیمایش را از طریق ترکیبی از محتوای قابل توجه و غیرقابل تمرکز آزمایش کنید.
- نمای وب. پیمایش از طریق پیوندها در یک
WebView
. -
FocusArea
سفارشی. تستFocusArea
سفارشی سازی:- بسته بندی
-
android:focusedByDefault
وapp:defaultFocus
. - اهداف صریح و شفاف.
- میانبرهای Nudge.
-
FocusArea
بدون دیدگاه قابل توجه.