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

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

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

  1. उस गतिविधि के लेआउट में FocusParkingView लगाएं.
  2. पक्का करें कि ऐसे व्यू जिन पर फ़ोकस किया जा सकता हो या नहीं किया जा सकता.
  3. फ़ोकस करने लायक सभी व्यू को शामिल करने के लिए 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. टूलबार में सबसे नीचे दिए गए तीन बिंदुओं पर टैप करें:

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

<FrameLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
   <com.android.car.ui.FocusParkingView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
   <FrameLayout
       android:layout_width="match_parent"
       android:layout_height="match_parent"/>
</FrameLayout>

FocusParkingView की ज़रूरत इन वजहों से हुई है:

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

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

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

पसंद के मुताबिक स्थिति

पसंद के मुताबिक स्थिति जोड़ने के लिए:

  1. कस्टम एट्रिब्यूट जोड़ने के लिए तक सीमित नहीं होना चाहिए. उदाहरण के लिए, state_rotary_enabled CustomView क्लास देखें, इसका इस्तेमाल करें:
    <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() के कॉल के साथ.

फ़ोकसएरिया

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

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

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

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

FocusArea का एक उदाहरण RotaryPlayground को नीचे दिखाया गया है:

<com.android.car.ui.FocusArea
       android:layout_margin="16dp"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="vertical">
       <EditText
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:singleLine="true">
       </EditText>
   </com.android.car.ui.FocusArea>

FocusArea इस तरह काम करता है:

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

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

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

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

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

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

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

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

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

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

नज शॉर्टकट
तीसरी इमेज. ईमेल का जवाब देने के लिए रिमाइंडर देने का शॉर्टकट

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

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

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

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

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

डिफ़ॉल्ट फ़ोकस हाइलाइट, Android फ़्रेमवर्क से मिलता है और इसे बदला जा सकता है की ओर से शेयर किया जा सकता है. ऐप्लिकेशन डेवलपर को यह तब मिलता है, जब वे जिस थीम का इस्तेमाल कर रहे होते हैं वह Theme.DeviceDefault.

उपयोगकर्ताओं को एक जैसा अनुभव देने के लिए, जब भी मुमकिन हो, फ़ोकस हाइलाइट का इस्तेमाल करें. अगर आपको पसंद के मुताबिक (जैसे, गोल या गोली के आकार वाला) फ़ोकस हाइलाइट की ज़रूरत है या आपको Theme.DeviceDefault से नहीं ली गई थीम का इस्तेमाल करके, कार-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>

(Android 11 QPR3, Android 11 कार, Android 12) सैंपल में बोल्ड संसाधन के रेफ़रंस कार-ui-लाइब्रेरी के ज़रिए तय किए गए संसाधनों की पहचान करें. OEM इन नियमों को एक जैसा रखता है का इस्तेमाल करें. इससे यह पक्का होता है कि फ़ोकस हाइलाइट रंग, स्ट्रोक की चौड़ाई, और जब उपयोगकर्ता कस्टम फ़ोकस के साथ एक व्यू से दूसरे व्यू पर जाता है, तो स्ट्रोक की चौड़ाई नहीं बदलती हाइलाइट और डिफ़ॉल्ट फ़ोकस हाइलाइट वाला एक व्यू. अंतिम आइटम स् पर्श करने के लिए उपयोग किया जाने वाला रिपल है. बोल्ड रिसॉर्स के लिए इस्तेमाल की जाने वाली डिफ़ॉल्ट वैल्यू इस तरह दिखती हैं:

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

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

सॉलिड बैकग्राउंड कलर
  • (Android 11 QPR3, Android 11 कार, 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 कार, Android 12)
अगर फ़ोकस करने लायक और फ़ोकस न करने लायक, दोनों तरह का कॉन्टेंट है या सभी एलिमेंट पर फ़ोकस नहीं किया जा सकता, तो रोटरी स्क्रोलिंग को चालू किया जा सकता है. इससे आपको उपयोगकर्ता को रोटरी कंट्रोलर का इस्तेमाल करना होगा, ताकि वह बिना स्किप किए सूची को धीरे-धीरे स्क्रोल कर सके फ़ोकस न किए जा सकने वाले आइटम. रोटरी स्क्रोलिंग चालू करने के लिए, app:rotaryScrollEnabled को सेट करें एट्रिब्यूट की वैल्यू true को दें.

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

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

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

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

सीधे तौर पर हेर-फेर करने वाला मोड

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

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

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

आसान तरीका

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

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

बेहतर तरीका

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

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

  1. (Android 11 QPR3, Android 11 कार, Android 12) के लिए, KEYCODE_DPAD_CENTER को सुनना ज़रूरी है इवेंट को DM मोड में ले जाने के लिए और DM मोड से बाहर निकलने के लिए, 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. यह बताने के लिए एक विज़ुअल क्यू देना चाहिए कि व्यू 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 फ़ोकस करने लायक नहीं होना चाहिए.
  • (Android 11 QPR3, Android 11 कार, अब यह सुविधा, Android 11 में काम नहीं करती)
    ActivityView के कॉन्टेंट में FocusParkingView शामिल होना चाहिए फ़ोकस करने लायक पहले व्यू के तौर पर शामिल किया और उसका app:shouldRestoreFocus विशेषता false होनी चाहिए.
  • ActivityView के कॉन्टेंट में ऐसा नहीं होना चाहिए android:focusByDefault व्यू.

उपयोगकर्ता के लिए, ActivityViews का उस फ़ोकस के अलावा नेविगेशन पर कोई प्रभाव नहीं होना चाहिए क्षेत्रों में ऐक्टिविटी व्यू नहीं हैं. दूसरे शब्दों में कहें, तो आपके पास एक ऐसा फ़ोकस एरिया नहीं हो सकता ActivityView में और उसके बाहर कॉन्टेंट है. अगर आप Google को आपके ActivityView के लिए, किसी अन्य FocusAres का इस्तेमाल करें, जो 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 एम्युलेटर बिल्ड और इसमें शामिल है Android Automotive OS (AAOS) पर चलने वाले डिवाइसों के लिए बनाया गया.

  • RotaryPlayground डेटा स्टोर करने की जगह: packages/apps/Car/tests/RotaryPlayground/
  • वर्शन: Android 11 QPR3, Android 11 Car, Android 12 के लिए

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

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