مطالب زیر برای توسعه دهندگان برنامه است.
برای اینکه برنامه خود را به صورت چرخشی پشتیبانی کنید، باید:
- یک
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یاengbuild استفاده کنید. - فعال کردن فیلتر رویداد کلیدی:
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; } - کاری کنید که کنترل کننده کلیک نمای شما بسته به وضعیت آن عملکرد متفاوتی داشته باشد. به عنوان مثال، کنترل کننده کلیک ممکن است کاری انجام ندهد یا زمانی که
mRotaryEnabledfalseاست، یک نان تست ظاهر شود. - برای اینکه دکمه غیرفعال به نظر برسد، در پسزمینه نمای خود، به جای
android:state_enabledapp: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یاengbuild استفاده کنید. - فعال کردن فیلتر رویداد کلیدی:
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; } - کاری کنید که کنترل کننده کلیک نمای شما بسته به وضعیت آن عملکرد متفاوتی داشته باشد. به عنوان مثال، کنترل کننده کلیک ممکن است کاری انجام ندهد یا زمانی که
mRotaryEnabledfalseاست، یک نان تست ظاهر شود. - برای اینکه دکمه غیرفعال به نظر برسد، در پسزمینه نمای خود، به جای
android:state_enabledapp: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:bottomBoundOffsetapp: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) گوش فرا دهد. - اگر نمای می خواهد چرخش را کنترل کند ، باید به
MotionEventS گوش داده و تعداد چرخش را در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بدون دیدگاه قابل توجه.


