Google NavigationView
はDesign Support Libraryバージョン22.2.0でを導入しました。これを使用すると、メニューリソースを使用して非常に簡単に引き出しを作成できます。
2つのアイテムの間に単純な分割線を作成するにはどうすればよいですか?アイテムのグループ化が機能しませんでした。サブアイテムセクションを作成すると区切り線が作成されますが、タイトルが必要ですが、これは不要です。
任意の助けいただければ幸いです。
Google NavigationView
はDesign Support Libraryバージョン22.2.0でを導入しました。これを使用すると、メニューリソースを使用して非常に簡単に引き出しを作成できます。
2つのアイテムの間に単純な分割線を作成するにはどうすればよいですか?アイテムのグループ化が機能しませんでした。サブアイテムセクションを作成すると区切り線が作成されますが、タイトルが必要ですが、これは不要です。
任意の助けいただければ幸いです。
回答:
必要なのはgroup
、一意のIDを使用してを定義することだけです。グループに異なる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>
setChecked
は、グループレベルで機能するように見えることです。グループAのアイテムを選択してから、もう一度ドロワーを開いてグループBのアイテムを選択すると、両方のアイテムが強調表示されたままになります。たぶん、Googleは次のリリースでこの動作を修正するかもしれませんが、現時点では、NavigationViewで複数のグループを使用することの欠点です。
android:checkableBehavior="none"
2番目のグループ(ナビゲーションではなくアクション)を試してください
group
コンパイルされて実行されますが、仕切りが非表示になります。
このようなドローアブルのdrawer_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"/>
navMenuView.addItemDecoration(new DividerItemDecoration(NavigationViewActivity.this, DividerItemDecoration.VERTICAL));
完璧なアイテムの境界線のためにやった
単純にDeviderItemDecorationを追加します。
NavigationView navigationView = (NavigationView) findViewById(R.id.navigation);
NavigationMenuView navMenuView = (NavigationMenuView) navigationView.getChildAt(0);
navMenuView.addItemDecoration(new DividerItemDecoration(MainActivity.this,DividerItemDecoration.VERTICAL));
それはこのように見えます:
addItemDecoration
行の高さを1px に変更できますか?
を使用して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>
結果:
複数のチェックされたアイテムの問題に対するさらに良い解決策があると思います。私の方法を使用すると、メニューに新しいセクションを追加するときにコードを変更することを心配する必要はありません。私のメニューは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>
「すべて」のcheckableBehaviorを使用すると、単一のアイテムが属するグループに関係なく、自由にチェック/チェック解除できます。最後にチェックしたメニューアイテムを保存するだけです。java-codeは次のようになります。
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;
}
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);
}
android:checkableBehavior="none"
これが修正されたのAPI 26 (Android 8)
か、それとも常に可能だったのかはわかりません。私はまだAndroidプログラミングの初心者です。ただし、以下のように親グループを追加しました。Android 6物理電話でのテスト
nav_g1
またはいずれかのアイテムを選択すると、nav_g2
他のアイテムの選択が解除されます。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>
ノート
android:checkableBehavior="single"
親グループのためで選択した複数のメニュー項目の問題よう要求され、この(hungryghostのコメントで述べた)答えは発生しません。そして、これがスクリーンショットです
最初のアイテムの上と最後のアイテムの後にディバイダーが欲しかった。@Nileshソリューションを使用して、ダミーのメニューアイテムを追加し、enabledを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>
編集:
ボタンの代わりに、元のメニュー項目の外観を模倣するドローアブルで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>
クレジットは解決策として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つあります。
<?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 = "single"
一意のIDで問題を解決する
装飾的なセパレータが必要だが、「チェック可能な動作」の問題のために複数のグループを作成したくない場合は、以前の回答に加えて、すべてのグループに同じグループ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>
選択した回答がうまくいかない場合はonCreateOptionsMenu
、一意のグループIDを追加するだけでなく、これに追加してみてください。
if (Build.VERSION.SDK_INT >= 28) {
menu.setGroupDividerEnabled(true)
}