नए नेविगेशन दृश्य में एक साधारण डिवाइडर कैसे बनाएं?


154

Google ने NavigationViewडिज़ाइन सपोर्ट लाइब्रेरी संस्करण 22.2.0 में पेश किया, जिसके साथ आप मेनू संसाधन का उपयोग करके आसानी से एक ड्रॉअर बना सकते हैं।

मैं दो मदों के बीच एक साधारण विभाजक रेखा कैसे बना सकता हूं? आइटमों को समूहीकृत करने से काम नहीं चला। एक उप आइटम अनुभाग बनाने से एक विभक्त रेखा बनती है, लेकिन इसके लिए एक शीर्षक की आवश्यकता होती है, जो मुझे नहीं चाहिए।

किसी भी सहायता की सराहना की जाएगी।


जैसा कि टिप्पणियों में कहा गया है, स्वीकृत उत्तर के साथ समस्या यह है कि चेक करने योग्य व्यवहार कई (समानांतर) समूहों में काम नहीं करता है। इससे बचने के लिए, समानांतर समूह न बनाएं, बल्कि अपने डिवाइडर को प्राप्त करने के लिए उप मेनू या उप समूहों का उपयोग करें जैसा कि मेरे उत्तर में यहां दिया गया है: stackoverflow.com/questions/30766919/…
तक

जवाबों:


319

आपको केवल groupएक विशिष्ट आईडी के साथ परिभाषित करने की आवश्यकता है , मैंने कार्यान्वयन की जांच की है यदि समूह में अलग-अलग आईडी है तो यह एक विभक्त पैदा करेगा।

उदाहरण मेनू, विभाजक बनाना:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

    <group android:id="@+id/grp1" android:checkableBehavior="single" >
        <item
            android:id="@+id/navigation_item_1"
            android:checked="true"
            android:icon="@drawable/ic_home"
            android:title="@string/navigation_item_1" />
    </group>

    <group android:id="@+id/grp2" android:checkableBehavior="single" >
        <item
            android:id="@+id/navigation_item_2"
            android:icon="@drawable/ic_home"
            android:title="@string/navigation_item_2" />
    </group>
</menu>

9
आश्चर्य है कि ऐसा क्यों है (जहाँ तक मुझे पता है) प्रलेखित नहीं है। मुझे लगता है कि यह बहुत पूछा जाएगा। धन्यवाद!
गोटन

16
इस दृष्टिकोण के साथ एक समस्या यह है कि setCheckedयह समूह स्तर पर काम करता है। यदि आप Group A में किसी आइटम का चयन करते हैं, तो फिर से दराज खोलें और Group B में आइटम का चयन करें, दोनों आइटम हाइलाइट रहेंगे। हो सकता है कि Google इस व्यवहार को अगली रिलीज़ में ठीक कर देगा, लेकिन अभी के लिए, यह नेविगेशन दृश्य वाले कई समूहों का उपयोग करने का नकारात्मक पक्ष है।
भूखाघर

3
महान। डबल चेक किए गए के बारे में, android:checkableBehavior="none"अपने दूसरे समूह के लिए प्रयास करें (जो कि कार्य हैं, नेविगेशन नहीं है, मुझे लगता है)
एस्पिनची

12
मजेदार बात यह है कि यदि आप आईडी को हटाते हैं तो groupयह संकलित और चलेगा लेकिन डिवाइडर छिपा हुआ है।
वाहिद अमीरी

5
यह मेरे लिए भी काम नहीं करता है। मुझे मेनू समूहों के बीच लाइनें चाहिए थीं, प्रत्येक आइटम के बाद नहीं।
रिच मोरे

54

इस तरह एक drawable_item_bg.xml ड्रा करने योग्य बनाएं ,

    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <shape android:shape="rectangle" >
            <solid android:color="#F4F4F4" />
        </shape>
    </item>

    <item android:top="-2dp" android:right="-2dp" android:left="-2dp">
        <shape>
            <solid android:color="@android:color/transparent" />
            <stroke
                android:width="1dp"
                android:color="#EAEAEA" />
        </shape>
        <!--
        android:dashGap="10px"
                android:dashWidth="10px"
                -->
    </item>

</layer-list>

और इसे ऐप के रूप में नेविगेशन दृश्य में जोड़ें : itemBackground = "@ drawable / drawer_item_bg"

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:background="#F4F4F4"
        android:layout_gravity="start"
        android:fitsSystemWindows="false"
        app:menu="@menu/activity_main_drawer"
        app:itemBackground="@drawable/drawer_item_bg"/>

और अब हम चले...यहाँ छवि विवरण दर्ज करें


1
यह काम करता है, लेकिन यह आइटम आइकन के बाईं गद्दी को भी हटा देता है। कम से कम मेरे कोड में, किसी कारण से आपके स्क्रीनशॉट में नहीं है
luky

@vbp मुझे पहले बच्चे के लिए शीर्ष सीमा चाहिए, दूसरे बच्चे के लिए नीचे की सीमा। मैं कैसे हासिल कर सकता था। यह कुछ वैसा ही है जैसा कि css में id.first बच्चे
Prbs

@Prabs बेहतर अनुकूलन के लिए नैविगेशन व्यू के बजाय एक टुकड़े, रिसाइकलव्यू या कस्टम दृश्यों का उपयोग करने पर विचार करते हैं
vbp

1
मैंने navMenuView.addItemDecoration(new DividerItemDecoration(NavigationViewActivity.this, DividerItemDecoration.VERTICAL));परफेक्ट आइटम बॉर्डर के लिए किया है
Prbs

19

सरल जोड़ें DeviderItemDecoration:

NavigationView navigationView = (NavigationView) findViewById(R.id.navigation);
NavigationMenuView navMenuView = (NavigationMenuView) navigationView.getChildAt(0);
navMenuView.addItemDecoration(new DividerItemDecoration(MainActivity.this,DividerItemDecoration.VERTICAL));

यह इस तरह दिखता है:

यहाँ छवि विवरण दर्ज करें


क्या मैं addItemDecorationलाइन की ऊंचाई को 1px में बदल सकता हूं ?
प्रात

धन्यवाद आपके समाधान ने मेरे लिए काम किया। मैं सराहना करता हूं। इसके साथ एक और प्रश्न भाई। क्या पहले आइटम के लिए शीर्ष सीमा को हटाने और केवल आइटम के नीचे की सीमा निर्धारित करना संभव है?
सांप

: @viper इस संदर्भ लें bignerdranch.com/blog/...
सनत

1
प्रत्येक आइटम के लिए इस तरह का डिवाइडर मटेरियल गाइलाइडलाइन का पालन नहीं करता है
बोरिस रुज़ानोव

19

आप XML का उपयोग करके मेनू आइटम पृष्ठभूमि सेट करके आसानी से डिवाइडर जोड़ सकते हैं app:itemBackground

<android.support.design.widget.NavigationView
    android:id="@id/drawer_navigation_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:menu="@menu/all_navigation_menu"
    app:itemIconTint="@color/colorPrimary"
    app:itemBackground="@drawable/bg_drawer_item"
    android:background="@color/default_background"/>

और बैकग्राउंड के रूप में LayerDrawable का उपयोग करें । यह क्लिक के लिए सामग्री डिज़ाइन रिपल ओवरले को संरक्षित करता है।

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white"/>
        </shape>
    </item>
    <item android:left="@dimen/activity_horizontal_margin">
        <shape android:shape="rectangle">
            <solid android:color="@color/divider"/>
        </shape>
    </item>
    <item android:bottom="1dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/white"/>
        </shape>
    </item>
</layer-list>

परिणाम:

यहाँ छवि विवरण दर्ज करें


2
सबसे अच्छा जवाब लगता है और इसमें कोई समूह शामिल नहीं है
मिशाल ज़ियोब्रो

यदि आप चयनित आइटम के लिए एक कस्टम पृष्ठभूमि रंग का उपयोग करना चाहते हैं तो क्या होगा?
अरावती

मेरे पास एक त्रुटि है <size>: यहां तत्व की अनुमति नहीं है
Sébastien REMY

11

मुझे लगता है कि मेरे पास कई जाँच की गई वस्तुओं की समस्या का बेहतर समाधान है। मेरे तरीके का उपयोग करके आपको अपने मेनू में नए अनुभाग जोड़ते समय अपना कोड बदलने के बारे में चिंता करने की आवश्यकता नहीं है। मेरा मेनू ठीक उसी तरह दिखता है जैसे कि जेरेड द्वारा लिखित स्वीकार किए जाते हैं, उपयोग और शून्य के अंतर के साथ: समूहों पर checkableBehavior = " all ":

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:id="@+id/first_section" android:checkableBehavior="all">
        <item
            android:id="@+id/frontpage"
            android:icon="@drawable/ic_action_home_24dp_light_blue"
            android:title="@string/drawer_frontpage" />
        <item
            android:id="@+id/search"
            android:icon="@drawable/ic_search"
            android:title="@string/drawer_search" />
    </group>
    <group android:id="@+id/second_section" android:checkableBehavior="all">
        <item
            android:id="@+id/events"
            android:icon="@drawable/ic_maps_local_movies_24dp_light_blue"
            android:title="@string/drawer_events" />
    </group>
</menu>

'सभी' का चेकेबल व्यवहार, एकल आइटम को स्वतंत्र रूप से जाँचना / अनचेक करना संभव बनाता है, स्वतंत्र रूप से वे किस समूह से हैं। आपको बस अंतिम चेक किए गए मेनूइटेम को स्टोर करना होगा। जावा-कोड इस तरह दिखता है:

private MenuItem activeMenuItem;

@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
    // Update selected/deselected MenuItems
    if (activeMenuItem != null)
        activeMenuItem.setChecked(false);
    activeMenuItem = menuItem;
    menuItem.setChecked(true);

    drawerLayout.closeDrawers();
    return true;
}

8

नीलेश के जवाब की तरह अलग-अलग समूह बनाने से बीच में एक विभक्त हो जाता है, लेकिन नौ दराज में दो चेक किए गए आइटम की समस्या पैदा करता है।

एक आसान तरीका है कि मैंने इसे कैसे संभाला:

    public boolean onNavigationItemSelected(final MenuItem menuItem) {

    //if an item from extras group is clicked,refresh NAV_ITEMS_MAIN to remove previously checked item
    if (menuItem.getGroupId() == NAV_ITEMS_EXTRA) {


        navigationView.getMenu().setGroupCheckable(NAV_ITEMS_MAIN, false, true);
        navigationView.getMenu().setGroupCheckable(NAV_ITEMS_EXTRA, true, true);
       }else{

        navigationView.getMenu().setGroupCheckable(NAV_ITEMS_MAIN, true, true);
        navigationView.getMenu().setGroupCheckable(NAV_ITEMS_EXTRA, false, true);


    }
    //Update highlighted item in the navigation menu
    menuItem.setChecked(true);
}

और भी सरल:android:checkableBehavior="none"
espinchi

2
@espinchi - यह काम नहीं करेगा यदि अन्य समूहों में नेविगेशन मेनू आइटम हैं। यह समाधान केवल कार्यों के लिए काम कर सकता है। अच्छा UX अभ्यास नहीं
मुश्ताक जमील

अति उत्कृष्ट! यह स्पष्ट हो सकता है यदि आपने अपने अपरिभाषित स्थिरांक NAV_ITEMS_MAIN और NAV_ITEMS_EXTRA को R.id.nav_items_group_main या R.id.nav_items_group_extra से बदल दिया और अपने उदाहरण के लिए आवश्यक XML जोड़ें
ChrisPrime

OnNavigationItemSelected (अंतिम MenuItem menuItem) {डिफ़ॉल्ट विधि ?? मुझे यह कोड कहां करना चाहिए?
जॉन

और NAV_ITEMS_MAIN क्या है ??
जॉन

8

मुझे यकीन नहीं है कि यह तय है API 26 (Android 8)या यह हर समय संभव था। मैं अभी भी एंड्रॉइड प्रोग्रामिंग में एक नॉब हूं। हालाँकि मैंने नीचे के रूप में मूल समूह जोड़े हैं। एंड्रॉइड 6 भौतिक फोन पर परीक्षण,

  1. मेरे पास विभक्त है
  2. nav_g1या तो किसी भी आइटम का चयन करना या nav_g2अन्य वस्तुओं का चयन रद्द करना होगा।
  3. नेस्टेड समूहों के कारण कोई अतिरिक्त पैडिंग नहीं जोड़ा गया।
  4. मैंने Javaश्रोताओं के लिए कोई कोड नहीं जोड़ा

मेनू कोड

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <group
            android:id="@+id/nav_g1"
            android:checkableBehavior="single">
            <item
                android:id="@+id/nav_1"
                android:icon="@drawable/ic_menu_share"
                android:title="@string/nav_1"/>
            <item
                android:id="@+id/nav_2"
                android:icon="@drawable/ic_menu_share"
                android:title="@string/nav_2"/>
        </group>
        <group
            android:id="@+id/nav_g2"
            android:checkableBehavior="single">
            <item
                android:id="@+id/nav_3"
                android:icon="@drawable/ic_menu_share"
                android:title="@string/nav_3"/>
            <item
                android:id="@+id/nav_4"
                android:icon="@drawable/ic_menu_share"
                android:title="@string/nav_4"/>
        </group>
    </group>
    <item android:title="Actions">
        <menu>
            <item
                android:id="@+id/nav_7"
                android:icon="@drawable/ic_menu_share"
                android:title="@string/nav_7"/>
            <item
                android:id="@+id/nav_8"
                android:icon="@drawable/ic_menu_share"
                android:title="@string/nav_8"/>
        </menu>
    </item>
</menu>

टिप्पणियाँ

  1. जैसा कि इस उत्तर में बताया गया है कि प्रत्येक समूह को विभक्त को दिखाने के लिए एक विशिष्ट आईडी की आवश्यकता होती है।
  2. इस उत्तर के अनुसार रिक्त स्थान Google सामग्री डिज़ाइन स्पेक्स से मेल खा रहे हैं।
  3. बीत रहा है android:checkableBehavior="single"मूल समूह के लिए आवश्यक है इसलिए में एकाधिक चयनित मेनू आइटम की समस्या इस जवाब (hungryghost द्वारा टिप्पणी में उल्लेख किया है) नहीं होता है

और यहाँ स्क्रीनशॉट है

डिवाइस स्क्रीन का स्क्रीनशॉट


5

मैं पहले आइटम के ऊपर और अंतिम आइटम के बाद डिवाइडर चाहता था। @ निलेश समाधान का उपयोग करते हुए मुझे डमी मेनू आइटम जोड़ना पड़ा और झूठे को सक्षम करना पड़ा जो वास्तव में गंदा लगा। प्लस क्या होगा अगर मैं अपने मेनू में अन्य शांत सामान करना चाहता हूं?

मैंने देखा कि नेवीगेशन व्यू फ्रेमलैट को बढ़ाता है ताकि आप अपनी सामग्री उसमें डाल सकें जैसे आप फ्रेमलेयआउट के लिए करेंगे। मैंने तब एक खाली मेनू xml सेट किया ताकि यह केवल मेरे कस्टम लेआउट को दिखाए। मैं समझता हूं कि यह संभवतः उस पथ के विरुद्ध है जिसे Google हमें लेना चाहता है लेकिन यदि आप वास्तव में कस्टम मेनू चाहते हैं तो यह एक आसान तरीका है।

<!--Note: NavigationView extends FrameLayout so we can put whatever we want in it.-->
<!--I don't set headerLayout since we can now put that in our custom content view-->
<android.support.design.widget.NavigationView
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:menu="@menu/empty_menu">

    <!--CUSTOM CONTENT-->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- CUSTOM HEADER -->
        <include
            android:id="@+id/vNavigationViewHeader"
            layout="@layout/navigation_view_header"/>

        <!--CUSTOM MENU-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_below="@+id/vNavigationViewHeader">

            <View style="@style/NavigationViewLineSeperator"/>

            <Button android:text="Option 1"/>

            <View style="@style/NavigationViewLineSeperator"/>

            <Button android:text="Option 2"/>

            <View style="@style/NavigationViewLineSeperator"/>

        </LinearLayout>
    </RelativeLayout>
</android.support.design.widget.NavigationView>

यहाँ शैली है

<style name="NavigationViewLineSeperator">
        <item name="android:background">@drawable/line_seperator</item>
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">1dp</item>
</style>

और आकर्षित करने योग्य

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="@color/white"/>
    <size android:width="100sp"
          android:height="1sp" />
</shape>

और मेनू

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
</menu>

संपादित करें:

बटन के बजाय आप ड्रा करने योग्य टेक्स्ट टेक्स्ट का उपयोग कर सकते हैं जो मूल मेनू आइटम की नकल करते हैं:

 <TextView
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:text="@string/menu_support"
     android:drawableLeft="@drawable/menu_icon_support"
     style="@style/MainMenuText" />

// style.xml
<style name="MainMenuText">
    <item name="android:drawablePadding">12dp</item>
    <item name="android:padding">10dp</item>
    <item name="android:gravity">center_vertical</item>
    <item name="android:textColor">#fff</item>
</style>

1
धन्यवाद, जाहिरा तौर पर मेनू आइटम के रूप में कस्टम दृश्य होने का सबसे सुविधाजनक तरीका है
जन रब

मैं इस समाधान का उपयोग इसलिए भी करता हूं क्योंकि इससे मुझे वस्तुओं के कस्टम फ़ॉन्ट को सेट करने और डिवाइडर के रंग को बदलने में मदद
मिलती है

1

समाधान के लिए क्रेडिट को ज़ोरावर जाना चाहिए, जवाब को नक़ल करने के लिए क्षमा करें, लेकिन एक टिप्पणी के भीतर इतना स्वरूपित पाठ नहीं जोड़ सका।

ज़ोरावर का समाधान काम करता है, कोड को इस तरह से बेहतर बनाया जा सकता है:

public void onNavigationItemSelected(int groupId) {

    //if an item from extras group is clicked,refresh NAV_ITEMS_MAIN to remove previously checked item
    navigationView.getMenu().setGroupCheckable(NAV_ITEMS_MAIN, (groupId == NAV_ITEMS_MAIN), true);
    navigationView.getMenu().setGroupCheckable(NAV_ITEMS_EXTRA, (groupId == NAV_ITEMS_EXTRA), true);


    //Update highlighted item in the navigation menu
    menuItem.setChecked(true);
}

NAV_ITEMS_MAIN और NAV_ITEMS_EXTRA और समूह क्या है ??
जॉन

वे Group_id के लिए स्थिरांक हैं
मुश्ताक जमील

0

निलेह का उत्तर सही है, सिवाय इसके कि दोहरी जाँच का एक दोष है।

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <group android:checkableBehavior="single" android:id="@+id/grp1">
        <item
            android:id="@+id/nav_register_customer"
            android:icon="@drawable/ic_menu_camera"
            android:checkableBehavior="none"
            android:title="Register Customer" />
    </group>
    <group  android:id="@+id/grp2"
        android:checkableBehavior="single"  >
        <item
            android:id="@+id/nav_slideshow"
            android:icon="@drawable/ic_menu_slideshow"
            android:checkableBehavior="none"
            android:title="Slideshow" />
    </group>
</menu>

इसलिए उपयोग कर रहे हैं

एंड्रॉयड: checkableBehavior = "एकल"

यूनिक आईडी से समस्या का समाधान होगा


0

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

Menu menu = navigationView.getMenu();
menu.addSubMenu(" ").add(" ");

यह एक विभक्त जोड़ देगा।

उपयोग करते समय सही सूचकांक में पास होना सुनिश्चित करें menu.getItem(int index)


0

पिछले उत्तरों के अलावा यदि आप सजावटी विभाजक चाहते हैं, लेकिन "जांच योग्य व्यवहार" समस्याओं के कारण कई समूह नहीं बनाना चाहते हैं - तो आप अपने सभी समूहों को एक ही समूह आईडी दे सकते हैं।

उदाहरण:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
    android:id="@+id/group_nav_common" <!-- New group id-->
    android:checkableBehavior="single">

    <item
        android:id="@+id/menu_item_nav_home"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/nav_menu_main" />
    <item
        android:id="@+id/menu_item_nav_articles"
        android:icon="@drawable/ic_art_track_black_24dp"
        android:title="@string/latest_news" />

    <item
        android:id="@+id/menu_item_nav_group_categories"
        android:title="@string/nav_menu_sections">
        <menu>
            <group
                android:id="@id/group_nav_common" <!-- Existing group id -->
                android:checkableBehavior="single">
                <!-- Programmatically populated section -->
            </group>
        </menu>
    </item>

    <item
        android:id="@+id/menu_item_nav_group_sites"
        android:title="@string/nav_menu_sites">
        <menu>
            <group
                android:id="@id/group_nav_common" <!-- Existing group id -->
                android:checkableBehavior="single">
                <item
                    android:id="@+id/menu_item_nav_select_site"
                    android:icon="@drawable/ic_account_balance_black_24dp"
                    android:title="@string/nav_menu_select_site" />
            </group>
        </menu>
    </item>
</group>


0

यदि चयनित उत्तर आपके लिए काम नहीं करता है, तो आप onCreateOptionsMenuअद्वितीय समूह आईडी देने के अतिरिक्त इसे जोड़ने का प्रयास करना चाहते हैं :

if (Build.VERSION.SDK_INT >= 28) {
    menu.setGroupDividerEnabled(true)
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.