web-dev-qa-db-ja.com

新しいNavigationViewで単純な画線を作成する方法

Googleは、デザインサポートライブラリのバージョン22.2.0でNavigationViewを導入しました。これを使用すると、メニューリソースを使用して非常に簡単に引き出しを作成できます。

2つの項目間に単純な区切り線を作成する方法アイテムをグループ化してもうまくいきませんでした。サブアイテムのセクションを作成しても分割線は作成されますが、タイトルが必要です。

任意の助けがいただければ幸いです。

141
Longi

あなたがする必要があるのは一意のIDgroupを定義することだけです、グループが異なるIDを持っているかどうか実装をチェックしました、それはデバイダを作成します。

メニューの例、セパレータの作成:

<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>
299
N J

このようにdrawabledrawer_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>

app:itemBackground = "@ drawable/drawer_item_bg"のようにNavigationViewに追加します。

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

そしてここで私達は行きます… screenshot

44
vbp

単純にDeviderItemDecorationを追加します。

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

それはこのように見えます:

enter image description here

16
SANAT

私は私が複数のチェックされた項目の問題に対してさらに良い解決策を持っていると思います。私の方法を使えば、メニューに新しいセクションを追加するときにコードを変更することを心配する必要はありません。私のメニューはJaredが書いた一般的な解決策のように見えますが、グループではandoid: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>

'all'のcheckableBehaviorは、それらがどのグループに属しているかとは無関係に、自由に単一のアイテムをチェック/チェック解除することを可能にします。最後にチェックしたメニューアイテムを保存するだけです。 Javaコードは次のようになります。

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;
}
11
plexus

app:itemBackgroundを使用してXMLでメニュー項目の背景を設定することで、仕切りを簡単に追加できます。

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

結果:

enter image description here

11

Nileshの答えのように異なるグループを作ることはそれらの間に仕切りを作りますが、ナビゲーション引き出しの中に2つのチェックされた項目の問題を引き起こします。

私がこれをどのように処理したか簡単な方法は、次のとおりです。

    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);
}
8
Zorawar Sachdev

これがAPI 26 (Android 8)で修正されているのか、それともずっと可能だったのかわかりません。私はまだAndroidのプログラミングに慣れていません。しかし、私は以下のように親グループを追加しました。 Android 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. this で説明したように、各グループはディバイダを表示するために一意のIDを持つ必要があります。
  2. this 回答スペースは、Googleのマテリアルデザイン仕様に一致しています。
  3. 親グループにAndroid:checkableBehavior="single"を持つことが必要なので、 this answer(hungryghostのコメントで言及されています)で複数の選択されたメニュー項目の問題は起こりません

これがスクリーンショットです

Screenshot of the device screen

7
AaA

私は最初の項目の上と最後の項目の後に仕切りが欲しいと思いました。 @Nileshのソリューションを使用して、私はダミーのメニュー項目を追加し、本当に汚い感じのfalseに有効に設定する必要がありました。さらに、メニューで他のクールなものを作りたい場合はどうすればよいですか。

私はNavigationViewがFrameLayoutを拡張することに気付いたので、あなたがあなたがFrameLayoutをするのと同じようにあなた自身のコンテンツをそれに入れることができる。次に、空のメニュー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>

編集:

ボタンの代わりに、元のメニュー項目を模したdrawable付きのTextViewを使用できます。

 <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>
5
Justin Fiedler

クレジットは解決のためにZorawarに行くべきです、答えを複製して申し訳ありませんが、コメントの中にそんなにフォーマットされたテキストを追加することができませんでした。

Zorawarのソリューションはうまくいきます、コードはそのように改良されることができました:

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);
}
1
Mushtaq Jameel

除算器を追加したい場合動的に、あなたはこのように空のSubMenuを追加することができます:

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

これは分割線を追加します。

menu.getItem(int index)を使うときは、必ず正しいインデックスを渡してください。

0

Nilehの答えは正しいです、それが二重チェックの1つの欠陥があることを除いて、正しいです。

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

だから使う

Android:checkableBehavior = "シングル"

一意のIDで問題を解決します

0
Ajji

選択した答えがうまくいかない場合は、一意のグループIDを指定するだけでなく、これをonCreateOptionsMenuに追加してみてください。

if (Build.VERSION.SDK_INT >= 28) {
    menu.setGroupDividerEnabled(true)
}
0
user806696

装飾的な区切り文字が必要でも「チェック可能な動作」の問題で複数のグループを作成したくない場合は、以前の回答に加えて、すべてのグループに同じグループIDを割り当てることができます。

例:

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