Google NavigationView은 메뉴 리소스를 사용하여 서랍을 매우 쉽게 만들 수있는 디자인 지원 라이브러리 버전 22.2.0을 도입했습니다 .
두 항목 사이에 간단한 구분선을 만들려면 어떻게해야합니까? 항목을 그룹화하지 못했습니다. 하위 항목 섹션을 만들면 구분선이 만들어 지지만 원하지 않는 제목이 필요합니다.
도움을 주시면 감사하겠습니다.
Google NavigationView은 메뉴 리소스를 사용하여 서랍을 매우 쉽게 만들 수있는 디자인 지원 라이브러리 버전 22.2.0을 도입했습니다 .
두 항목 사이에 간단한 구분선을 만들려면 어떻게해야합니까? 항목을 그룹화하지 못했습니다. 하위 항목 섹션을 만들면 구분선이 만들어 지지만 원하지 않는 제목이 필요합니다.
도움을 주시면 감사하겠습니다.
답변:
당신이해야 할 일은 고유 ID로를 정의하는 것 group입니다. 그룹이 다른 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"번째 그룹 (탐색이 아닌 동작)을 시도 하십시오.
group하면 컴파일되고 실행되지만 디바이더는 숨겨져 있다는 것입니다.
이와 같이 drawable 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>
결과:
여러 개의 체크 된 항목의 문제에 대해 더 나은 해결책이 있다고 생각합니다. 내 방식을 사용하면 메뉴에 새 섹션을 추가 할 때 코드 변경에 대해 걱정할 필요가 없습니다. 내 메뉴는 그룹에서 andoid : checkableBehavior = " all "을 사용하는 것과는 달리 Jared가 작성한 허용 된 솔루션과 같습니다.
<?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를 사용하면 그룹에 관계없이 단일 항목을 마음대로 확인 / 선택 취소 할 수 있습니다. 마지막으로 확인한 메뉴 항목 만 저장하면됩니다. 자바 코드는 다음과 같습니다.
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의 답변과 같은 다른 그룹을 만들면 사이에 구분이 이루어 지지만 탐색 창에서 두 개의 확인 된 항목의 문제가 발생합니다.
내가 이것을 처리하는 간단한 방법은 다음과 같습니다.
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 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 솔루션을 사용하여 더미 메뉴 항목을 추가하고 실제로 더럽게 느껴지는 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);
}
Nileh의 답변은 옳습니다. 단 하나의 이중 확인 결함이 있습니다.
<?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로 문제를 해결해야합니다.
장식적인 구분 기호를 원하지만 "확인 가능한 동작"문제로 인해 여러 그룹을 만들지 않으려는 경우 이전 답변 외에도 모든 그룹에 동일한 그룹 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>