ऐप्लिकेशन डेवलप करना

यह कॉन्टेंट, ऐप्लिकेशन डेवलपर के लिए है.

अपने ऐप्लिकेशन को रोटरी मोड के साथ काम करने लायक बनाने के लिए, आपको ये काम करने होंगे:

  1. उस गतिविधि के लेआउट में FocusParkingView डालें.
  2. पक्का करें कि वे व्यू फ़ोकस किए जा सकते हों या नहीं.
  3. FocusParkingView को छोड़कर, फ़ोकस किए जा सकने वाले सभी व्यू के चारों ओर रैप करने के लिए, FocusArea का इस्तेमाल करें.

रोटरी मोड वाले ऐप्लिकेशन बनाने के लिए, इनवायरनमेंट सेट अप करने के बाद, इनमें से हर टास्क के बारे में यहां बताया गया है.

रोटरी कंट्रोलर सेट अप करना

रोटरी कंट्रोल की सुविधा वाले ऐप्लिकेशन डेवलप करने से पहले, आपके पास रोटरी कंट्रोल वाला डिवाइस या रोटरी कंट्रोल की सुविधा देने वाला स्टैंड-इन होना चाहिए. आपके पास ये विकल्प हैं.

एम्युलेटर

source build/envsetup.sh && lunch car_x86_64-userdebug
m -j
emulator -wipe-data -no-snapshot -writable-system

इसके अलावा, aosp_car_x86_64-userdebug का इस्तेमाल भी किया जा सकता है.

एमुलेट किए गए रोटरी कंट्रोलर को ऐक्सेस करने के लिए:

  1. टूलबार में सबसे नीचे मौजूद तीन बिंदुओं पर टैप करें:

    एमुलेट किए गए रोटरी कंट्रोलर को ऐक्सेस करना
    पहला इलस्ट्रेशन. एमुलेट किए गए रोटरी कंट्रोलर को ऐक्सेस करना
  2. एक्सटेंडेड कंट्रोल विंडो में, कार रोटरी चुनें:

    कार रोटरी चुनें
    दूसरी इमेज. कार रोटरी चुनें

यूएसबी कीबोर्ड

  • Android Automotive OS (AAOS) वाले अपने डिवाइस में यूएसबी कीबोर्ड प्लग करें. कुछ मामलों में, इससे ऑन-स्क्रीन कीबोर्ड नहीं दिखता.
  • userdebug या eng बिल्ड का इस्तेमाल करें.
  • मुख्य इवेंट को फ़िल्टर करने की सुविधा चालू करना:
    adb shell settings put secure android.car.ROTARY_KEY_EVENT_FILTER 1
    
  • हर कार्रवाई के लिए उससे जुड़ी कुंजी ढूंढने के लिए, नीचे दी गई टेबल देखें:
    सुरक्षा कुंजी रोटरी ऐक्शन
    Q घड़ी की उलटी दिशा में घुमाएं
    E घड़ी की दिशा में घुमाएं
    A हल्का सा बाएं करें
    D थोड़ा दाएं करें
    W हल्का सा ऊपर करें
    S थोड़ा सा नीचे करें
    F या कॉमा सेंटर बटन
    R या Esc 'वापस जाएं' बटन

ADB निर्देश

रोटरी इनपुट इवेंट इंजेक्ट करने के लिए, car_service निर्देशों का इस्तेमाल किया जा सकता है. ये निर्देश, Android Automotive OS (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, कार की यूज़र इंटरफ़ेस (यूआई) लाइब्रेरी (car-ui-library) में एक पारदर्शी व्यू है. RotaryService इसका इस्तेमाल, रोटरी कंट्रोलर नेविगेशन के साथ काम करने के लिए करता है. FocusParkingView, लेआउट में फ़ोकस किया जा सकने वाला पहला व्यू होना चाहिए. इसे सभी FocusArea के बाहर रखा जाना चाहिए. हर विंडो में एक FocusParkingView होना चाहिए. अगर आपने पहले से ही car-ui-library के बेस लेआउट का इस्तेमाल किया है, जिसमें FocusParkingView है, तो आपको कोई दूसरा FocusParkingView जोड़ने की ज़रूरत नहीं है. यहां RotaryPlayground में FocusParkingView का उदाहरण दिया गया है.

<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 की ज़रूरत क्यों है, इस बारे में यहां बताया गया है:

  1. जब फ़ोकस किसी दूसरी विंडो में सेट होता है, तो Android फ़ोकस को अपने-आप हटा नहीं देता. अगर आपने पिछली विंडो से फ़ोकस हटाने की कोशिश की, तो Android उस विंडो में फिर से फ़ोकस कर देता है. इससे, एक साथ दो विंडो पर फ़ोकस हो जाता है. हर विंडो में FocusParkingView जोड़कर, इस समस्या को ठीक किया जा सकता है. यह व्यू पारदर्शी होता है और इसमें फ़ोकस हाइलाइट करने की डिफ़ॉल्ट सुविधा बंद होती है. इसलिए, उपयोगकर्ता को यह नहीं दिखता कि किसी एलिमेंट पर फ़ोकस किया गया है या नहीं. यह फ़ोकस ले सकता है, ताकि RotaryService उस पर फ़ोकस पार्क कर सके और फ़ोकस हाइलाइट हटा सके.
  2. अगर मौजूदा विंडो में सिर्फ़ एक FocusArea है, तो FocusArea में कंट्रोलर को घुमाने पर, RotaryService का फ़ोकस दाईं ओर के व्यू से बाईं ओर के व्यू पर चला जाता है. इसके अलावा, बाईं ओर के व्यू से दाईं ओर के व्यू पर भी फ़ोकस चलाया जा सकता है. हर विंडो में यह व्यू जोड़कर, समस्या को ठीक किया जा सकता है. जब RotaryService यह तय करता है कि फ़ोकस टारगेट FocusParkingView है, तो यह यह तय कर सकता है कि व्यू में रैप-अराउंड होने वाला है. इस स्थिति में, यह फ़ोकस को दूसरी जगह ले जाने से रोककर, रैप-अराउंड से बचता है.
  3. जब रोटरी कंट्रोल से कोई ऐप्लिकेशन लॉन्च किया जाता है, तो Android उस व्यू पर फ़ोकस करता है जिस पर फ़ोकस किया जा सकता है. आम तौर पर, यह FocusParkingView होता है. FocusParkingView यह तय करता है कि फ़ोकस करने के लिए कौनसा व्यू सबसे सही है. इसके बाद, फ़ोकस लागू करता है.

फ़ोकस करने लायक व्यू

RotaryService, व्यू फ़ोकस के लिए Android फ़्रेमवर्क के मौजूदा कॉन्सेप्ट पर आधारित है. यह कॉन्सेप्ट, फ़ोन में फ़िज़िकल कीबोर्ड और डी-पैड के समय से मौजूद है. मौजूदा android:nextFocusForward एट्रिब्यूट को रोटरी के लिए फिर से इस्तेमाल किया गया है (FocusArea को पसंद के मुताबिक बनाने का तरीका देखें), लेकिन android:nextFocusLeft, android:nextFocusRight, android:nextFocusUp, और android:nextFocusDown का इस्तेमाल नहीं किया गया है.

RotaryService सिर्फ़ उन व्यू पर फ़ोकस करता है जिन पर फ़ोकस किया जा सकता है. आम तौर पर, Button जैसे कुछ व्यू पर फ़ोकस किया जा सकता है. आम तौर पर, TextView और ViewGroup जैसे अन्य आइटम नहीं दिखाए जाते. क्लिक किए जा सकने वाले व्यू पर अपने-आप फ़ोकस किया जा सकता है. साथ ही, अगर व्यू में क्लिक मिलने की सूचना देने वाला कोई लिसनर है, तो व्यू पर अपने-आप क्लिक किया जा सकता है. अगर इस अपने-आप लागू होने वाले लॉजिक की वजह से, व्यू को फ़ोकस किया जा सकता है, तो आपको व्यू को फ़ोकस किया जा सकता है या नहीं, यह साफ़ तौर पर सेट करने की ज़रूरत नहीं है. अगर ऑटोमैटिक लॉजिक की वजह से, फ़ोकस करने की सुविधा ठीक से काम नहीं करती है, तो android:focusable एट्रिब्यूट को true या false पर सेट करें. इसके अलावा, View.setFocusable(boolean) की मदद से प्रोग्राम के हिसाब से व्यू की फ़ोकस करने की सुविधा सेट करें. RotaryService के उस पर फ़ोकस करने के लिए, व्यू को इन ज़रूरी शर्तों को पूरा करना होगा:

  • फ़ोकस करने लायक
  • चालू किया गया
  • दिखने वाली समीक्षाएं
  • चौड़ाई और ऊंचाई के लिए वैल्यू शून्य से ज़्यादा होनी चाहिए

अगर कोई व्यू इन सभी ज़रूरी शर्तों को पूरा नहीं करता है, तो उपयोगकर्ता उस पर फ़ोकस करने के लिए रोटरी कंट्रोल का इस्तेमाल नहीं कर सकता. उदाहरण के लिए, फ़ोकस किया जा सकने वाला, लेकिन बंद बटन. अगर आपको बंद किए गए व्यू पर फ़ोकस करना है, तो android:state_enabled के बजाय कस्टम स्टेटस का इस्तेमाल करें. इससे, यह कंट्रोल किया जा सकता है कि व्यू कैसे दिखे. साथ ही, यह भी नहीं बताया जा सकता कि Android को इसे बंद मानना चाहिए. आपका ऐप्लिकेशन, उपयोगकर्ता को यह जानकारी दे सकता है कि टैप करने पर व्यू बंद क्यों हो जाता है. अगले सेक्शन में, ऐसा करने का तरीका बताया गया है.

कस्टम स्टेटस

कस्टम स्टेटस जोड़ने के लिए:

  1. अपने व्यू में कस्टम एट्रिब्यूट जोड़ने के लिए. उदाहरण के लिए, CustomView व्यू क्लास में state_rotary_enabled कस्टम स्टेटस जोड़ने के लिए, इनका इस्तेमाल करें:
    <declare-styleable name="CustomView">
        <attr name="state_rotary_enabled" format="boolean" />
    </declare-styleable>
    
  2. इस स्टेटस को ट्रैक करने के लिए, ऐक्सेस करने के तरीकों के साथ-साथ अपने व्यू में एक इंस्टेंस वैरिएबल जोड़ें:
    private boolean mRotaryEnabled;
    public boolean getRotaryEnabled() { return mRotaryEnabled; }
    public void setRotaryEnabled(boolean rotaryEnabled) {
        mRotaryEnabled = rotaryEnabled;
    }
    
  3. व्यू बनाने के बाद, अपने एट्रिब्यूट की वैल्यू पढ़ने के लिए:
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
    mRotaryEnabled = a.getBoolean(R.styleable.CustomView_state_rotary_enabled);
    
  4. अपनी व्यू क्लास में, 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;
    }
    
  5. अपने व्यू के क्लिक हैंडलर को उसकी स्थिति के हिसाब से अलग-अलग तरीके से काम करने दें. उदाहरण के लिए, ऐसा हो सकता है कि क्लिक हैंडलर कुछ न करे या mRotaryEnabled के false होने पर, वह टोस्ट पॉप-अप कर दे.
  6. बटन को बंद दिखाने के लिए, अपने व्यू के बैकग्राउंड ड्रॉबल में, android:state_enabled के बजाय app:state_rotary_enabled का इस्तेमाल करें. अगर आपके पास पहले से यह जानकारी नहीं है, तो आपको यह जोड़ना होगा:
    xmlns:app="http://schemas.android.com/apk/res-auto"
    
  7. अगर आपका व्यू किसी भी लेआउट में बंद है, तो android:enabled="false" को app:state_rotary_enabled="false" से बदलें. इसके बाद, ऊपर बताए गए तरीके से app नेमस्पेस जोड़ें.
  8. अगर आपका व्यू प्रोग्राम के हिसाब से बंद है, तो setEnabled() के कॉल को setRotaryEnabled() के कॉल से बदलें.

FocusArea

फ़ोकस किए जा सकने वाले व्यू को ब्लॉक में बांटने के लिए, FocusAreas का इस्तेमाल करें. इससे नेविगेशन आसान हो जाता है और अन्य ऐप्लिकेशन के साथ भी काम करने में आसानी होती है. उदाहरण के लिए, अगर आपके ऐप्लिकेशन में कोई टूलबार है, तो टूलबार को ऐप्लिकेशन के बाकी हिस्सों से अलग FocusArea में रखा जाना चाहिए. टैब बार और अन्य नेविगेशन एलिमेंट को भी ऐप्लिकेशन के बाकी हिस्सों से अलग रखा जाना चाहिए. आम तौर पर, बड़ी सूचियों का अपना FocusArea होना चाहिए. अगर ऐसा नहीं है, तो कुछ व्यू ऐक्सेस करने के लिए, उपयोगकर्ताओं को पूरी सूची में घूमना होगा.

FocusArea, car-ui-library में LinearLayout का सबक्लास है. इस सुविधा के चालू होने पर, FocusArea के किसी वंशज पर फ़ोकस करने पर, वह हाइलाइट हो जाता है. ज़्यादा जानने के लिए, फ़ोकस हाइलाइट को पसंद के मुताबिक बनाना लेख पढ़ें.

लेआउट फ़ाइल में नेविगेशन ब्लॉक बनाते समय, अगर आपको उस ब्लॉक के लिए LinearLayout का इस्तेमाल कंटेनर के तौर पर करना है, तो इसके बजाय FocusArea का इस्तेमाल करें. इसके अलावा, ब्लॉक को FocusArea में रैप करें.

किसी FocusArea को किसी दूसरे FocusArea में नेस्ट करें. ऐसा करने से, नेविगेशन का व्यवहार तय नहीं होता. पक्का करें कि फ़ोकस किए जा सकने वाले सभी व्यू, FocusArea में नेस्ट किए गए हों.

RotaryPlayground में FocusArea का उदाहरण यहां दिया गया है:

<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 इस तरह काम करता है:

  1. घुमाने और धकेलने की कार्रवाइयों को मैनेज करते समय, RotaryService व्यू के लेआउट में FocusArea के उदाहरणों को खोजता है.
  2. रोटेशन इवेंट मिलने पर, RotaryService फ़ोकस को किसी ऐसे दूसरे व्यू पर ले जाता है जो उसी FocusArea में फ़ोकस ले सकता है.
  3. नज़द इवेंट मिलने पर, RotaryService फ़ोकस को किसी ऐसे दूसरे व्यू पर ले जाएं जो फ़ोकस को किसी दूसरे (आम तौर पर आस-पास के) FocusArea पर ले जा सकता है.

अगर आपने अपने लेआउट में कोई FocusAreas शामिल नहीं किया है, तो रूट व्यू को डिफ़ॉल्ट फ़ोकस एरिया माना जाता है. उपयोगकर्ता, ऐप्लिकेशन में नेविगेट करने के लिए नज़्ड नहीं कर सकता. इसके बजाय, वह फ़ोकस किए जा सकने वाले सभी व्यू को घुमाएगा. ये व्यू, डायलॉग के लिए काफ़ी हो सकते हैं.

फ़ोकस एरिया को पसंद के मुताबिक बनाना

रोटरी नेविगेशन को पसंद के मुताबिक बनाने के लिए, व्यू के दो स्टैंडर्ड एट्रिब्यूट का इस्तेमाल किया जा सकता है:

  • android:nextFocusForward की मदद से, ऐप्लिकेशन डेवलपर किसी फ़ोकस किए गए इलाके में, रोटेशन के क्रम को तय कर सकते हैं. यह वही एट्रिब्यूट है जिसका इस्तेमाल, कीबोर्ड नेविगेशन के लिए Tab के क्रम को कंट्रोल करने के लिए किया जाता है. लूप बनाने के लिए, इस एट्रिब्यूट का इस्तेमाल करें. इसके बजाय, लूप बनाने के लिए app:wrapAround (नीचे देखें) का इस्तेमाल करें.
  • android:focusedByDefault की मदद से, ऐप्लिकेशन डेवलपर विंडो में डिफ़ॉल्ट फ़ोकस व्यू तय कर सकते हैं. एक ही FocusArea में, इस एट्रिब्यूट और app:defaultFocus (नीचे देखें) का इस्तेमाल करें.

FocusArea, रोटरी नेविगेशन को पसंद के मुताबिक बनाने के लिए कुछ एट्रिब्यूट भी तय करता है. इन एट्रिब्यूट की मदद से, चुने गए फ़ोकस एरिया को पसंद के मुताबिक नहीं बनाया जा सकता.

  1. (Android 11 QPR3, Android 11 Car, Android 12)
    app:defaultFocus का इस्तेमाल, फ़ोकस किए जा सकने वाले वंश व्यू का आईडी बताने के लिए किया जा सकता है. जब उपयोगकर्ता इस FocusArea पर टैप करता है, तो इस पर फ़ोकस किया जाना चाहिए.
  2. (Android 11 QPR3, Android 11 Car, Android 12)
    app:defaultFocusOverridesHistory को true पर सेट किया जा सकता है, ताकि ऊपर बताए गए व्यू पर फ़ोकस किया जा सके. भले ही, इस FocusArea में किसी दूसरे व्यू पर फ़ोकस किया गया हो, ताकि इतिहास से पता चल सके.
  3. (Android 12)
    फ़ोकस किए जा सकने वाले वंश व्यू का आईडी बताने के लिए, app:nudgeLeftShortcut, app:nudgeRightShortcut, app:nudgeUpShortcut, और app:nudgeDownShortcut का इस्तेमाल करें. उपयोगकर्ता के किसी दिशा में झुकने पर, इस व्यू पर फ़ोकस किया जाना चाहिए. ज़्यादा जानने के लिए, सूचना देने वाले शॉर्टकट के बारे में नीचे दिया गया कॉन्टेंट देखें.

    (Android 11 QPR3, Android 11 Car, Android 12 में काम नहीं करता) app:nudgeShortcut और app:nudgeShortcutDirection में सिर्फ़ एक नडज शॉर्टकट काम करता है.

  4. (Android 11 QPR3, Android 11 Car, Android 12)
    इस FocusArea में रोटेशन को चारों ओर घुमाने की सुविधा चालू करने के लिए, app:wrapAround को true पर सेट किया जा सकता है. इसका इस्तेमाल आम तौर पर तब किया जाता है, जब व्यू को सर्कल या अंडाकार में व्यवस्थित किया जाता है.
  5. (Android 11 QPR3, Android 11 Car, Android 12)
    FocusArea में हाइलाइट के पैडिंग को अडजस्ट करने के लिए, app:highlightPaddingStart, app:highlightPaddingEnd, app:highlightPaddingTop, app:highlightPaddingBottom, app:highlightPaddingHorizontal, और app:highlightPaddingVertical का इस्तेमाल करें.
  6. (Android 11 QPR3, Android 11 Car, Android 12)
    नज्ड टारगेट ढूंढने के लिए, इस FocusArea की अनुमानित सीमाओं में बदलाव करने के लिए, app:startBoundOffset, app:endBoundOffset, app:topBoundOffset, app:bottomBoundOffset, app:horizontalBoundOffset, और app:verticalBoundOffset का इस्तेमाल करें.
  7. (Android 11 QPR3, Android 11 Car, Android 12)
    दिए गए निर्देशों में, आस-पास के FocusArea (या इलाकों) का आईडी साफ़ तौर पर बताने के लिए, app:nudgeLeft, app:nudgeRight, app:nudgeUp, और app:nudgeDown का इस्तेमाल करें. इसका इस्तेमाल तब करें, जब डिफ़ॉल्ट रूप से इस्तेमाल की जाने वाली ज्यामितीय खोज से, मनमुताबिक टारगेट न मिले.

आम तौर पर, न्युडिंग की सुविधा से फ़ोकस एरिया के बीच नेविगेट किया जाता है. हालांकि, नॉज शॉर्टकट की मदद से, कभी-कभी पहले FocusArea में नेविगेट किया जाता है, ताकि उपयोगकर्ता को अगले FocusArea पर नेविगेट करने के लिए, दो बार नॉज करना पड़े. 'धक्का दें' शॉर्टकट तब काम के होते हैं, जब FocusArea में एक लंबी सूची के बाद फ़्लोटिंग ऐक्शन बटन हो, जैसा कि यहां दिए गए उदाहरण में है:

सूचना भेजने का शॉर्टकट
तीसरी इमेज. रिमाइंडर भेजने का शॉर्टकट

नडज शॉर्टकट के बिना, उपयोगकर्ता को एफ़एबी तक पहुंचने के लिए पूरी सूची में घूमना पड़ेगा.

फ़ोकस हाइलाइट को पसंद के मुताबिक बनाना

जैसा कि ऊपर बताया गया है, RotaryService, व्यू फ़ोकस के Android फ़्रेमवर्क के मौजूदा कॉन्सेप्ट पर आधारित है. जब उपयोगकर्ता घुमाता है और झटका देता है, तो RotaryService फ़ोकस को एक से दूसरे व्यू पर ले जाता है. Android में, जब किसी व्यू पर फ़ोकस किया जाता है, तो अगर वह व्यू:

  • अपने फ़ोकस हाइलाइट की जानकारी दी है, तो Android व्यू का फ़ोकस हाइलाइट दिखाता है.
  • फ़ोकस हाइलाइट की जानकारी नहीं दी गई है और डिफ़ॉल्ट फ़ोकस हाइलाइट की सुविधा बंद नहीं है, तो Android व्यू के लिए डिफ़ॉल्ट फ़ोकस हाइलाइट दिखाता है.

टच के लिए डिज़ाइन किए गए ऐप्लिकेशन में, आम तौर पर फ़ोकस हाइलाइट की जानकारी नहीं दी जाती.

फ़ोकस हाइलाइट करने की डिफ़ॉल्ट सुविधा, 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 की मदद से तय किए गए संसाधनों की पहचान की जाती है. ओईएम, इन एट्रिब्यूट की वैल्यू को बदल देता है, ताकि वे डिफ़ॉल्ट फ़ोकस हाइलाइट के साथ मेल खा सकें. इससे यह पक्का होता है कि जब उपयोगकर्ता, कस्टम फ़ोकस हाइलाइट वाले व्यू और डिफ़ॉल्ट फ़ोकस हाइलाइट वाले व्यू के बीच स्विच करता है, तो फ़ोकस हाइलाइट का रंग, स्ट्रोक की चौड़ाई वगैरह न बदले. आखिरी आइटम, टच के लिए इस्तेमाल किया जाने वाला रिपल है. बोल्ड किए गए संसाधनों के लिए इस्तेमाल की गई डिफ़ॉल्ट वैल्यू इस तरह दिखती हैं:

बोल्ड किए गए संसाधनों के लिए डिफ़ॉल्ट वैल्यू
चौथी इमेज. बोल्ड किए गए संसाधनों के लिए डिफ़ॉल्ट वैल्यू

इसके अलावा, जब किसी बटन को उपयोगकर्ता का ध्यान खींचने के लिए, एकदम साफ़ बैकग्राउंड रंग दिया जाता है, तो कस्टम फ़ोकस हाइलाइट का इस्तेमाल किया जाता है. इसका उदाहरण नीचे दिया गया है. इससे फ़ोकस हाइलाइट को देखना मुश्किल हो सकता है. इस स्थिति में, सेकंडरी रंगों का इस्तेमाल करके, फ़ोकस हाइलाइट करने का तरीका तय करें:

बैकग्राउंड का एक रंग
  • (Android 11 QPR3, Android 11 Car, Android 12)
    car_ui_rotary_focus_fill_secondary_color
    car_ui_rotary_focus_stroke_secondary_color
  • (Android 12)
    car_ui_rotary_focus_pressed_fill_secondary_color
    car_ui_rotary_focus_pressed_stroke_secondary_color

उदाहरण के लिए:

फ़ोकस किया गया, लेकिन दबाया नहीं गया फ़ोकस किया गया, दबाया गया
फ़ोकस किया गया, लेकिन दबाया नहीं गया फ़ोकस किया गया, दबाया गया

रोटरी स्क्रोलिंग

अगर आपका ऐप्लिकेशन RecyclerView का इस्तेमाल करता है, तो आपको इसके बजाय CarUiRecyclerView का इस्तेमाल करना चाहिए. इससे यह पक्का होता है कि आपका यूज़र इंटरफ़ेस (यूआई) दूसरों के यूआई से मेल खाता हो, क्योंकि OEM का कस्टमाइज़ेशन सभी CarUiRecyclerView पर लागू होता है.

अगर आपकी सूची में मौजूद सभी एलिमेंट फ़ोकस किए जा सकते हैं, तो आपको कुछ और करने की ज़रूरत नहीं है. रोटरी नेविगेशन की मदद से, सूची में मौजूद एलिमेंट पर फ़ोकस किया जा सकता है. साथ ही, फ़ोकस किए गए नए एलिमेंट को दिखाने के लिए, सूची को स्क्रोल किया जा सकता है.

(Android 11 QPR3, Android 11 Car, Android 12)
अगर फ़ोकस किए जा सकने वाले और फ़ोकस नहीं किए जा सकने वाले एलिमेंट का मिश्रण है या सभी एलिमेंट फ़ोकस नहीं किए जा सकते, तो रोटरी स्क्रोलिंग की सुविधा चालू की जा सकती है. इससे उपयोगकर्ता, रोटरी कंट्रोलर का इस्तेमाल करके सूची में धीरे-धीरे स्क्रोल कर सकता है. ऐसा करने पर, फ़ोकस नहीं किए जा सकने वाले आइटम को स्किप नहीं किया जाता. रोटरी स्क्रोलिंग की सुविधा चालू करने के लिए, app:rotaryScrollEnabled एट्रिब्यूट को true पर सेट करें.

(Android 11 QPR3, Android 11 Car, Android 12)
CarUiUtils में दिए गए setRotaryScrollEnabled() तरीके का इस्तेमाल करके, स्क्रोल किए जा सकने वाले किसी भी व्यू में रोटरी स्क्रोलिंग की सुविधा चालू की जा सकती है. इसमें avCarUiRecyclerView भी शामिल है. ऐसा करने के लिए, आपको ये काम करने होंगे:

  • स्क्रोल किए जा सकने वाले व्यू को फ़ोकस किया जा सकता है, ताकि जब उसके किसी भी वंश व्यू पर फ़ोकस न किया जा सके, तो उस पर फ़ोकस किया जा सके,
  • स्क्रोल किए जा सकने वाले व्यू पर, डिफ़ॉल्ट रूप से फ़ोकस हाइलाइट करने की सुविधा बंद करने के लिए, setDefaultFocusHighlightEnabled(false) को कॉल करें, ताकि स्क्रोल किए जा सकने वाले व्यू पर, फ़ोकस न दिखे,
  • setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS) को कॉल करके, पक्का करें कि स्क्रोल किए जा सकने वाले व्यू पर, उसके डिसेंटेंट से पहले फ़ोकस किया गया हो.
  • SOURCE_ROTARY_ENCODER के साथ MotionEvents सुनें और स्क्रोल करने की दूरी और साइन के ज़रिए दिशा बताने के लिए, AXIS_VSCROLL या AXIS_HSCROLL में से किसी एक का इस्तेमाल करें.

जब CarUiRecyclerView पर रोटरी स्क्रोलिंग की सुविधा चालू होती है और उपयोगकर्ता किसी ऐसे हिस्से पर घुमाता है जहां फ़ोकस किए जा सकने वाले व्यू मौजूद नहीं होते, तो स्क्रोलबार का रंग स्लेटी से नीले में बदल जाता है. इससे पता चलता है कि स्क्रोलबार पर फ़ोकस किया गया है. अगर आपको पसंद है, तो इस तरह का इफ़ेक्ट लागू किया जा सकता है.

सोर्स को छोड़कर, MotionEvents वैसे ही होते हैं जैसे माउस पर स्क्रोल व्हील से जनरेट होते हैं.

डेटा में सीधे तौर पर बदलाव करने का मोड

आम तौर पर, यूज़र इंटरफ़ेस में नेविगेट करने के लिए, नॉब को थोड़ा दबाकर घुमाया जाता है. वहीं, सेंटर बटन को दबाकर कार्रवाई की जाती है. हालांकि, ऐसा हमेशा नहीं होता. उदाहरण के लिए, अगर किसी उपयोगकर्ता को अलार्म की आवाज़ कम या ज़्यादा करनी है, तो वह वॉल्यूम स्लाइडर पर जाने के लिए रोटरी कंट्रोलर का इस्तेमाल कर सकता है. इसके बाद, वह सेंटर बटन दबाकर, अलार्म की आवाज़ कम या ज़्यादा करने के लिए कंट्रोलर को घुमाएगा. इसके बाद, नेविगेशन पर वापस जाने के लिए, वह बैक बटन दबाएगा. इसे डायरेक्ट मैनिपुलेशन (डीएम) मोड कहा जाता है. इस मोड में, रोटरी कंट्रोलर का इस्तेमाल नेविगेट करने के बजाय, सीधे व्यू के साथ इंटरैक्ट करने के लिए किया जाता है.

डीएम को लागू करने के लिए, इनमें से कोई एक तरीका अपनाएं. अगर आपको सिर्फ़ रोटेशन मैनेज करना है और जिस व्यू में बदलाव करना है वह ACTION_SCROLL_FORWARD और ACTION_SCROLL_BACKWARD AccessibilityEvent के हिसाब से सही तरीके से काम करता है, तो आसान तरीके का इस्तेमाल करें. इसके अलावा, बेहतर तरीके का इस्तेमाल करें.

सिस्टम विंडो में, आसान तरीका ही एकमात्र विकल्प है. ऐप्लिकेशन, दोनों में से किसी भी तरीके का इस्तेमाल कर सकते हैं.

आसान तरीका

(Android 11 QPR3, Android 11 Car, Android 12)
आपके ऐप्लिकेशन को कॉल करना चाहिए DirectManipulationHelper.setSupportsRotateDirectly(View view, boolean enable). RotaryService यह पहचानता है कि उपयोगकर्ता डीएम मोड में है या नहीं. साथ ही, जब उपयोगकर्ता किसी व्यू पर फ़ोकस करते समय सेंटर बटन दबाता है, तो वह डीएम मोड में चला जाता है. डीएम मोड में होने पर, रोटेशन ACTION_SCROLL_FORWARD या ACTION_SCROLL_BACKWARD के हिसाब से होते हैं. साथ ही, उपयोगकर्ता के 'वापस जाएं' बटन दबाने पर, डीएम मोड बंद हो जाता है. यह आसान तरीका, डीएम मोड में जाने और उससे बाहर निकलने पर, व्यू की चुनी गई स्थिति को टॉगल करता है.

उपयोगकर्ता के डीएम मोड में होने की जानकारी देने के लिए, चुने जाने पर अपने व्यू को अलग दिखाएं. उदाहरण के लिए, जब android:state_selected true हो, तब बैकग्राउंड बदलें.

बेहतर तरीके

ऐप्लिकेशन यह तय करता है कि RotaryService डीएम मोड में कब जाएगा और कब उससे बाहर निकलेगा. उपयोगकर्ता को बेहतर अनुभव देने के लिए, डीएम व्यू पर फ़ोकस करके सेंटर बटन दबाने पर डीएम मोड चालू होना चाहिए और 'वापस जाएं' बटन दबाने पर डीएम मोड बंद होना चाहिए. अगर सेंटर बटन और/या नडज का इस्तेमाल नहीं किया जाता है, तो डीएम मोड से बाहर निकलने के लिए इनका इस्तेमाल किया जा सकता है. Maps जैसे ऐप्लिकेशन के लिए, डीएम मोड में जाने के लिए, डीएम को दिखाने वाले बटन का इस्तेमाल किया जा सकता है.

ऐडवांस डीएम मोड के साथ काम करने के लिए, व्यू:

  1. (Android 11 QPR3, Android 11 Car, Android 12) को डीएम मोड में जाने के लिए KEYCODE_DPAD_CENTER इवेंट और डीएम मोड से बाहर निकलने के लिए KEYCODE_BACK इवेंट को सुनना होगा. साथ ही, हर मामले में DirectManipulationHelper.enableDirectManipulationMode() को कॉल करना होगा. इन इवेंट को सुनने के लिए, इनमें से कोई एक तरीका अपनाएं:
    • OnKeyListener रजिस्टर करें.
    • या,
    • व्यू को बड़ा करें और फिर उसके dispatchKeyEvent() तरीके को बदलें.
  2. अगर व्यू में रिमाइंडर मैनेज करने की सुविधा हो, तो रिमाइंडर इवेंट (KEYCODE_DPAD_UP, KEYCODE_DPAD_DOWN, KEYCODE_DPAD_LEFT या KEYCODE_DPAD_RIGHT) के लिए सुनना चाहिए.
  3. अगर व्यू में रोटेशन को मैनेज करना है, तो MotionEvent को सुनना चाहिए और AXIS_SCROLL में रोटेशन की संख्या देखनी चाहिए. ऐसा करने के कई तरीके हैं:
    1. OnGenericMotionListener रजिस्टर करें.
    2. व्यू को बड़ा करें और उसके dispatchTouchEvent() तरीके को बदलें.
  4. डीएम मोड में फंसने से बचने के लिए, उस फ़्रैगमेंट या ऐक्टिविटी से बाहर निकलना ज़रूरी है जिससे व्यू जुड़ा है.
  5. यह बताने के लिए कि व्यू डीएम मोड में है, विज़ुअल क्यू दिया जाना चाहिए.

यहां कस्टम व्यू का एक सैंपल दिया गया है. इसमें मैप को पैन और ज़ूम करने के लिए, डीएम मोड का इस्तेमाल किया गया है:

/** 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 कार, Android 11 में बंद कर दिया गया)
    ActivityView के कॉन्टेंट में, फ़ोकस किए जा सकने वाले पहले व्यू के तौर पर FocusParkingView होना चाहिए. साथ ही, इसका app:shouldRestoreFocus एट्रिब्यूट false होना चाहिए.
  • ActivityView के कॉन्टेंट पर एक भी android:focusByDefault व्यू नहीं होना चाहिए.

उपयोगकर्ता के लिए, गतिविधि व्यू का नेविगेशन पर कोई असर नहीं पड़ना चाहिए. हालांकि, फ़ोकस एरिया, गतिविधि व्यू में नहीं दिख सकते. दूसरे शब्दों में, आपके पास एक ऐसा फ़ोकस एरिया नहीं हो सकता जिसमें ActivityView के अंदर और बाहर, दोनों जगह कॉन्टेंट हो. अगर आपने अपने ActivityView में कोई फ़ोकस एरिया नहीं जोड़ा है, तो ActivityView में व्यू हैरारकी का रूट, डिफ़ॉल्ट फ़ोकस एरिया माना जाता है.

ऐसे बटन जिन्हें दबाकर रखने पर वे काम करते हैं

ज़्यादातर बटन पर क्लिक करने पर कोई कार्रवाई होती है. कुछ बटन दबाकर रखने पर काम करते हैं. उदाहरण के लिए, फ़ास्ट फ़ॉरवर्ड और रीवाइंड बटन को दबाकर रखने पर, वे काम करते हैं. ऐसे बटनों को रोटरी बटन के तौर पर इस्तेमाल करने के लिए, KEYCODE_DPAD_CENTER KeyEvents को इस तरह सुनें:

mButton.setOnKeyListener((v, keyCode, event) ->
{
    if (keyCode != KEYCODE_DPAD_CENTER) {
        return false;
    }
    if (event.getAction() == ACTION_DOWN) {
        mButton.setPressed(true);
        mHandler.post(mRunnable);
    } else {
        mButton.setPressed(false);
        mHandler.removeCallbacks(mRunnable);
    }
    return true;
});

इसमें mRunnable कोई कार्रवाई करता है, जैसे कि वीडियो को पीछे ले जाना. साथ ही, वह खुद को कुछ समय बाद चलने के लिए शेड्यूल करता है.

टच मोड

कार में हेड यूनिट के साथ इंटरैक्ट करने के लिए, उपयोगकर्ता रोटरी कंट्रोलर का इस्तेमाल दो तरीकों से कर सकते हैं. पहला, रोटरी कंट्रोलर का इस्तेमाल करके और दूसरा, स्क्रीन को छूकर. रोटरी कंट्रोलर का इस्तेमाल करने पर, फ़ोकस किए जा सकने वाले व्यू में से एक को हाइलाइट किया जाता है. स्क्रीन को छूने पर, फ़ोकस हाइलाइट नहीं दिखता. उपयोगकर्ता इन इनपुट मोड के बीच किसी भी समय स्विच कर सकता है:

  • रोटरी → टच. जब उपयोगकर्ता स्क्रीन को टच करता है, तो फ़ोकस हाइलाइट हट जाती है.
  • टच → रोटरी. जब उपयोगकर्ता, सेंटर बटन को दबाता है, घुमाता है या उस पर टैप करता है, तो फ़ोकस हाइलाइट दिखता है.

इनपुट मोड पर, 'वापस जाएं' और 'होम' बटन का कोई असर नहीं पड़ता.

रोटरी, Android के टच मोड के मौजूदा कॉन्सेप्ट पर काम करता है. View.isInTouchMode() का इस्तेमाल करके, यह पता लगाया जा सकता है कि उपयोगकर्ता किस इनपुट मोड का इस्तेमाल कर रहा है. बदलावों को सुनने के लिए, OnTouchModeChangeListener का इस्तेमाल किया जा सकता है. इसका इस्तेमाल, मौजूदा इनपुट मोड के लिए यूज़र इंटरफ़ेस को पसंद के मुताबिक बनाने के लिए किया जा सकता है. हालांकि, इसमें कोई बड़ा बदलाव न करें, क्योंकि इससे परेशानी हो सकती है.

समस्या का हल

टच के लिए डिज़ाइन किए गए ऐप्लिकेशन में, नेस्ट किए गए फ़ोकस किए जा सकने वाले व्यू होना आम बात है. उदाहरण के लिए, ImageButton के आस-पास FrameLayout हो सकता है, जिस पर फ़ोकस किया जा सकता है. इससे टच कंट्रोल पर कोई असर नहीं पड़ता. हालांकि, रोटरी कंट्रोल के लिए उपयोगकर्ता अनुभव खराब हो सकता है, क्योंकि अगले इंटरैक्टिव व्यू पर जाने के लिए उपयोगकर्ता को कंट्रोलर को दो बार घुमाना पड़ता है. Google का सुझाव है कि उपयोगकर्ता को बेहतर अनुभव देने के लिए, बाहरी व्यू या अंदरूनी व्यू में से किसी एक पर फ़ोकस किया जा सकता है. हालांकि, दोनों पर फ़ोकस नहीं किया जा सकता.

अगर रोटरी कंट्रोलर से किसी बटन या स्विच को दबाने पर, उस पर फ़ोकस नहीं रहता है, तो इनमें से कोई एक स्थिति लागू हो सकती है:

  • बटन को दबाए जाने की वजह से, बटन या स्विच को थोड़े समय के लिए या हमेशा के लिए बंद किया जा रहा है. दोनों मामलों में, इस समस्या को ठीक करने के दो तरीके हैं:
    • android:enabled स्टेटस को true के तौर पर सेट करें और बटन या स्विच को स्लेटी रंग में दिखाने के लिए, कस्टम स्टेटस में बताए गए तरीके के हिसाब से कस्टम स्टेटस का इस्तेमाल करें.
    • बटन या स्विच को घेरने के लिए कंटेनर का इस्तेमाल करें और बटन या स्विच के बजाय, कंटेनर पर फ़ोकस करें. (क्लिक लिसनर, कंटेनर पर होना चाहिए.)
  • बटन या स्विच को बदला जा रहा है. उदाहरण के लिए, बटन दबाने या स्विच को टॉगल करने पर की गई कार्रवाई, उपलब्ध कार्रवाइयों को रीफ़्रेश कर सकती है. इससे, मौजूदा बटन की जगह नए बटन आ सकते हैं. इसे ठीक करने के दो तरीके हैं:
    • नया बटन या स्विच बनाने के बजाय, मौजूदा बटन या स्विच का आइकॉन और/या टेक्स्ट सेट करें.
    • ऊपर बताए गए तरीके से, बटन या स्विच के चारों ओर फ़ोकस किया जा सकने वाला कंटेनर जोड़ें.

RotaryPlayground

RotaryPlayground, रोटरी के लिए रेफ़रंस ऐप्लिकेशन है. इसका इस्तेमाल करके, अपने ऐप्लिकेशन में रोटरी सुविधाओं को इंटिग्रेट करने का तरीका जानें. RotaryPlayground को Android Automotive OS (AAOS) वाले डिवाइसों के लिए, एमुलेटर के बिल्ड और बिल्ड में शामिल किया गया है.

  • RotaryPlayground रिपॉज़िटरी: packages/apps/Car/tests/RotaryPlayground/
  • वर्शन: Android 11 QPR3, Android 11 Car, और Android 12

RotaryPlayground ऐप्लिकेशन में बाईं ओर ये टैब दिखते हैं:

  • कार्ड. फ़ोकस किए जा सकने वाले एलिमेंट और टेक्स्ट इनपुट को स्किप करके, फ़ोकस किए जा सकने वाले एलिमेंट पर नेविगेट करने की जांच करें.
  • डायरेक्ट मैनिपुलेशन. ऐसे विजेट की जांच करें जो सीधे मैनिपुलेशन मोड के आसान और बेहतर वर्शन के साथ काम करते हैं. यह टैब खास तौर पर, ऐप्लिकेशन विंडो में सीधे तौर पर बदलाव करने के लिए है.
  • सिस्टम यूज़र इंटरफ़ेस (यूआई) में बदलाव करना. उन विजेट की जांच करें जो सीधे तौर पर डेटा में बदलाव करने की सुविधा के साथ काम करते हैं और सिस्टम विंडो में सिर्फ़ सीधे तौर पर डेटा में बदलाव करने का आसान मोड काम करता है.
  • ग्रिड. स्क्रोल करके, z-पैटर्न रोटरी नेविगेशन की जांच करें.
  • सूचना. स्क्रीन पर सबसे ऊपर सूचना देने वाले कार्ड को नडज करने की सुविधा को टेस्ट करें.
  • स्क्रोल करें. फ़ोकस किए जा सकने वाले और फ़ोकस न किए जा सकने वाले कॉन्टेंट के मिश्रण की मदद से, स्क्रोलिंग की जांच करें.
  • वेबव्यू. WebView में लिंक पर नेविगेट करने की जांच करें.
  • पसंद के मुताबिक FocusArea. FocusArea को पसंद के मुताबिक बनाने की सुविधा को टेस्ट करना:
    • रैप-अराउंड.
    • android:focusedByDefault और app:defaultFocus
    • .
    • साफ़ तौर पर नडज करने वाले टारगेट.
    • सूचना देने के लिए शॉर्टकट.
    • FocusArea एलिमेंट में कोई फ़ोकस करने लायक व्यू नहीं है.