Yeni NavigationView'da basit bir ayırıcı nasıl oluşturulur?


154

Google, NavigationViewbir menü kaynağı kullanarak kolayca bir çekmece oluşturabileceğiniz Tasarım Destek Kütüphanesi 22.2.0 sürümünü tanıttı.

İki öğe arasında nasıl basit bir ayırıcı çizgi oluşturabilirim? Öğeleri gruplandırmak işe yaramadı. Alt öğeler bölümü oluşturmak bir ayırıcı çizgi oluşturur, ancak istemediğim bir başlık gerektirir.

Herhangi bir yardım mutluluk duyacağız.


Yorumlarda belirtildiği gibi, kabul edilen cevapla ilgili sorun, kontrol edilebilir davranışın birden fazla (paralel) grupta çalışmadığıdır. Bundan kaçınmak için paralel gruplar oluşturmayın, ancak bölücülerinizi buradaki cevabımda açıklandığı gibi almak için alt menüler veya alt gruplar kullanın: stackoverflow.com/questions/30766919/…
kadar

Yanıtlar:


319

Tek yapmanız gereken benzersiz bir kimlikgroup ile bir tanımlamak , grup farklı kimlikleri varsa bir bölücü oluşturacak uygulamayı kontrol ettim.

Örnek menü, ayırıcı oluşturma:

<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
Bunun neden bildiğim kadarıyla belgelenmediğini merak ediyorum. Bence çok sorulacak. Teşekkürler!
Gaëtan

16
Bu yaklaşımla ilgili tek sorun setChecked, grup düzeyinde çalışıyor gibi görünüyor. A Grubunda bir öğe seçerseniz, çekmeceyi tekrar açın ve B Grubunda öğe seçin, her iki öğe de vurgulanmış olarak kalır. Belki Google bu davranışı bir sonraki sürümde düzeltir, ancak şimdilik bu, NavigationView ile birden fazla grup kullanmanın dezavantajıdır.
hungryghost

3
Harika. Çift kontrol hakkında, android:checkableBehavior="none"ikinci grubunuzu deneyin (bu eylemler, navigasyon değil, sanırım)
espinchi

12
Komik şey, eğer kimliği çıkarırsanız groupderler ve çalışır, ancak bölücüler gizlenir.
Vahid Amiri

5
Bu benim için de işe yaramıyor. Her gruptan sonra değil, menü grupları arasında çizgiler istedim.
Rich Morey

54

bunun gibi çekilebilir bir drawer_item_bg.xml oluşturun ,

    <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>

ve bunu NavigationView uygulamasına uygulama olarak ekleyin : 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"/>

ve işte başlıyoruz ...resim açıklamasını buraya girin


1
bu çalışır, ancak öğe simgesinin sol dolgusunu da kaldırır. en azından
kodumda

@vbp İlk çocuk için üst sınıra, diğer çocuk için de alt sınıra ihtiyacım var. Nasıl başarabilirim. Css'deki id.first çocuğuna benzer bir şey
Prabs

@Praplar, daha iyi özelleştirme için NavigationView yerine bir parça, geri dönüşüm görünümü veya özel görünüm kullanmayı düşünüyor
vbp

1
navMenuView.addItemDecoration(new DividerItemDecoration(NavigationViewActivity.this, DividerItemDecoration.VERTICAL));Mükemmel eşya sınırı için yaptım
Prabs

19

Basit DeviderItemDecoration ekleyin:

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

Şuna benziyor:

resim açıklamasını buraya girin


addItemDecorationSatır yüksekliğini 1 piksel olarak değiştirebilir miyim ?
Prabs

Teşekkür ederim çözümün benim için çalıştı. Takdir ediyorum. Abi bu konuda bir soru daha. İlk öğenin üst kenarlığını kaldırmak ve yalnızca öğelerin altına sınır koymak mümkün müdür?
engerek

@viper lütfen buna bakın: bignerdranch.com/blog/…
SANAT

1
Her bir öğe için bu tür bölücüler takip etmiyor Materyal Guyidelines
Boris Ruzanov

19

XML kullanarak Menü Öğesi Arkaplanını XML aracılığıyla ayarlayarak kolayca bölücüler ekleyebilirsiniz 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"/>

Ve arka plan olarak LayerDrawable kullanın . Tıklamalar için malzeme tasarımı dalgalanma katmanını korur.

<?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>

Sonuç:

resim açıklamasını buraya girin


2
en iyi cevap gibi görünüyor ve hiçbir grup dahil değil
Michał Ziobro

Seçilen öğe için özel bir arka plan rengi kullanmak isterseniz ne olur?
ataravati

<shape> ile ilgili bir hata var: Öğeye burada izin verilmiyor
Sébastien REMY

11

Birden fazla kontrol edilen öğenin sorunu için daha iyi bir çözümüm olduğunu düşünüyorum. Yolumu kullanarak menünüze yeni bölümler eklerken kodunuzu değiştirme konusunda endişelenmenize gerek yok. Menüm , gruplarda andoid kullanmanın farkı ile Jared tarafından yazılan kabul edilen çözüme benziyor: checkableBehavior = " all " grupları:

<?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>

'All' öğesinin checkableBehavior, hangi gruba ait olduklarından bağımsız olarak, istedikleri zaman tek tek öğeleri kontrol etmeyi / işaretini kaldırmayı mümkün kılar. Son kontrol edilen menü öğesini saklamanız yeterlidir. Java kodu şöyle görünür:

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

Nilesh'ın cevabı gibi farklı gruplar yapmak aralarında bir ayırıcı yapar Ama gezinme çekmecesinde kontrol edilen iki öğenin problemini yaratır.

Bunu nasıl ele aldığımın basit bir yolu:

    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);
}

Daha da basit:android:checkableBehavior="none"
espinchi

2
@espinchi - Diğer gruplar gezinme menüsü öğeleri içeriyorsa çalışmaz. Bu çözüm yalnızca eylemler için kullanılabilir. İyi değil UX uygulaması
Mushtaq Jameel

Mükemmel! Tanımsız sabitlerinizi NAV_ITEMS_MAIN ve NAV_ITEMS_EXTRA ile R.id.nav_items_group_main veya R.id.nav_items_group_extra değiştirdiyseniz ve örneğinize gerekli XML'yi eklerseniz daha açık olabilir
ChrisPrime

IS onNavigationItemSelected (son MenuItem menuItem) {Varsayılan yöntem ?? bu kodu nerede yapmalıyım?
John

ve NAV_ITEMS_MAIN nedir ??
John

8

Bunun düzeltildiğinden API 26 (Android 8)veya her zaman mümkün olduğundan emin değilim . Android programlamada hala bir çaylakım. Ancak aşağıdaki gibi ana grupları ekledim. Android 6 fiziksel telefonda test etme,

  1. Bölücüm var
  2. Herhangi bir öğeden herhangi birini seçmek nav_g1veya nav_g2diğer öğelerin seçimini kaldırır.
  3. İç içe gruplar nedeniyle fazladan dolgu eklenmez.
  4. JavaDinleyicilere kod eklemedim

Menü Kodu

<?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>

notlar

  1. Bu cevapta belirtildiği gibi, her grubun bölücüyü göstermek için benzersiz bir kimliği olması gerekir.
  2. Gereğince bu cevap alanlarda google malzeme tasarımı özelliklerini eşleştirme.
  3. Having android:checkableBehavior="single"birden seçilen menü öğelerinin sorun böylesine üst grubun gereklidir bu (hungryghost tarafından yorum olarak bahsedilen) cevap olmaz

Ve işte ekran görüntüsü

Cihaz ekranının ekran görüntüsü


5

İlk öğenin üstünde ve son öğeden sonra bölücüler istedim. @Nilesh çözüm kullanarak kukla menü öğeleri eklemek ve gerçekten kirli hissettim false olarak ayarlanmış vardı. Ayrıca menümde başka harika şeyler yapmak istersem ne olur?

NavigationView'ın, kendi içeriğinizi tıpkı bir FrameLayout için yaptığınız gibi koyabileceğiniz şekilde FrameLayout'u genişlettiğini fark ettim. Sonra sadece benim özel düzeni göstermek için boş bir menü xml ayarladım. Bunun muhtemelen Google'ın bizim istediğimiz yola aykırı olduğunu biliyorum ama gerçekten özel bir menü istiyorsanız bunu yapmanın kolay bir yoludur.

<!--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>

İşte tarz

<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>

Ve çekilebilir

<?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>

Ve menü

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

Düzenle:

Düğmeler yerine, orijinal menü öğelerinin görünüşünü taklit eden çekilebilir TextView kullanabilirsiniz:

 <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
teşekkürler, görünüşe göre menü öğeleri olarak özel görünümlere sahip en uygun yolu
Jan Rabe

Bu çözümü de kullanıyorum çünkü öğelerin özel yazı tipini ayarlamamı ve bölücü rengini değiştirmemi sağlıyor
luky

1

Kredi, çözüm için Zorawar'a gitmeli, Cevabı çoğalttığım için üzgünüm, ancak bir yorumda çok fazla biçimlendirilmiş metin ekleyemedim.

Zorawar'ın çözümü işe yarar, kod şu şekilde geliştirilebilir:

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 ve NAV_ITEMS_EXTRA ve grup kimliği nedir ??
John

Bunlar group_id
Mushtaq Jameel

0

Nil'in cevabı haklı, tek bir çifte kontrol kusuru dışında.

<?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>

Yani kullanarak

android: checkableBehavior = "tek"

benzersiz kimliği ile sorunu çözecektir


0

Dinamik olarak bölücü eklemek istiyorsanız, aşağıdaki gibi boş bir SubMenu ekleyebilirsiniz:

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

bu bir bölücü ekleyecektir.

kullanırken doğru dizini ilettiğinizden emin olun menu.getItem(int index)


0

Dekoratif ayırıcılar istiyorsanız, ancak "denetlenebilir davranış" sorunları nedeniyle birden çok grup oluşturmak istemiyorsanız, önceki yanıtlara ek olarak, aynı grup kimliğini tüm gruplarınıza atayabilirsiniz.

Misal:

<?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

Seçilen cevap sizin için işe yaramazsa onCreateOptionsMenu, benzersiz grup kimliği vermek için buna eklemeyi de deneyebilirsiniz :

if (Build.VERSION.SDK_INT >= 28) {
    menu.setGroupDividerEnabled(true)
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.