Android支持:设计NavigationView勾选菜单子项
Posted
技术标签:
【中文标题】Android支持:设计NavigationView勾选菜单子项【英文标题】:Android support:design NavigationView checked menu sub items 【发布时间】:2015-08-27 01:59:31 【问题描述】:我最近开始转换我的 android 应用程序以使用名为 support:design 的最新支持库。
在实现新的 NavigationView 时,我偶然发现了显示所选菜单项的问题。
我的 navdrawer_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/navigation_item_home"
android:icon="@drawable/ic_home_black"
android:title="@string/navdrawer_item_home" />
</group>
<item
android:id="@+id/navigation_subheader"
android:title="@string/navdrawer_subheader_title1">
<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/navigation_sub_item1"
android:icon="@drawable/ic_home_black"
android:title="@string/navdrawer_sub_item1" />
</group>
</menu>
</item>
</menu>
接下来我将菜单项设置为检查我的 onNavigationItemSelected:
@Override
public boolean onNavigationItemSelected(final MenuItem menuItem)
menuItem.setChecked(true);
drawerLayout.closeDrawer(GravityCompat.START);
mDrawerActionHandler.postDelayed(new Runnable()
@Override
public void run()
displayView(menuItem.getItemId());
, DRAWER_CLOSE_DELAY_MS);
return true;
如果我只在标签之间使用普通菜单项,这非常有用,但它不适用于子标题。单击子项目不会将它们设置为选中,直到我单击同一项目两次并且它不会取消选中之前检查过的任何项目。
它最终看起来像这样:
【问题讨论】:
这是一个android支持库错误:code.google.com/p/android/issues/detail?id=175216 【参考方案1】:每个项目都必须在一个组内,因此该组可以控制项目在用户选择时的视觉行为。试试看:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/navigation_item_home"
android:icon="@drawable/ic_home_black"
android:title="@string/navdrawer_item_home" />
<item
android:id="@+id/navigation_subheader"
android:title="@string/navdrawer_subheader_title1">
<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/navigation_sub_item1"
android:icon="@drawable/ic_home_black"
android:title="@string/navdrawer_sub_item1" />
</group>
</menu>
</item>
</group>
</menu>
【讨论】:
@JohnVandenBerg 如果此答案或任何答案解决了您的问题,请单击复选标记考虑accepting it。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。【参考方案2】:我以这种非常有效的方式解决了这个反复出现的问题。
我们必须简单地记住所选项目的 id,在 NavigationView 上为您的菜单充值并再次选择该项目。
为此,您需要像这样使用菜单抽屉:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/section_1"
android:title="@string/section_title">
<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/item_1_section_1"
android:icon="@drawable/ic_icon"
android:title="@string/title"/>
<item
android:id="@+id/item_2_section_1"
android:icon="@drawable/ic_icon"
android:title="@string/title"/>
...
</group>
</menu>
</item>
...
<item
android:id="@+id/section_x"
android:title="@string/section_title">
<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/item_1_section_x"
android:icon="@drawable/ic_icon"
android:title="@string/title"/>
<item
android:id="@+id/item_2_section_x"
android:icon="@drawable/ic_icon"
android:title="@string/title"/>
...
</group>
</menu>
</item>
</menu>
所以,我的解决方案:
public class YourActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener
...
private NavigationView mNavigationView;
private int mNavItemId;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
...
// load saved navigation state if present
if (null == savedInstanceState)
mNavItemId = R.id.item_1_section_1;
else
mNavItemId = savedInstanceState.getInt(NAV_ITEM_ID);
// listen for navigation events
mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
mNavigationView.setNavigationItemSelectedListener(this);
// select the correct nav menu item
mNavigationView.getMenu().findItem(mNavItemId).setChecked(true);
@Override
public boolean onNavigationItemSelected(final MenuItem menuItem)
// update highlighted item in the navigation menu
mNavItemId = menuItem.getItemId();
// allow some time after closing the drawer before performing real navigation
// so the user can see what is happening
mDrawerLayout.closeDrawer(GravityCompat.START);
mDrawerActionHandler.postDelayed(new Runnable()
@Override
public void run()
...
, DRAWER_CLOSE_DELAY_MS);
// Reload menuDrawer to keep selected item
mNavigationView.getMenu().clear();
mNavigationView.inflateMenu(R.menu.menu_drawer);
mNavigationView.getMenu().findItem(mNavItemId).setChecked(true);
return true;
...
【讨论】:
这似乎可以完成这项工作,但是当我这样做时,它只会加载第一组菜单。有什么想法吗?【参考方案3】:这很简单。 只需为每个项目添加 android:checkable="true"。
例如。
<item
android:id="@+id/navigation_item_home"
android:icon="@drawable/ic_home_black"
android:title="@string/navdrawer_item_home"
android:checkable="true" />
【讨论】:
【参考方案4】:我建议采用@MichelFortes 提供的解决方案,因为它解决了我在 NavigationView 中的子菜单项的问题。这是我的代码,它可以工作
<group android:checkableBehavior="single">
<item
android:id="@+id/your_id_item"
android:icon="@drawable/your_icon_if_you_want"
android:title="@string/title_for_this_item" />
<!-- you can add here as many items as you want -->
</group>
<item
android:title="@string/submenu_title">
<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/submenu_item_id"
android:icon="@drawable/icon_if_exists"
android:title="@string/title_for_item" />
<!-- you can add here as many items as you want -->
</group>
</menu>
</item>
在这里,您选择的每个项目都会被选中并突出显示! 再次感谢@MichelFortes ;)
【讨论】:
以上是关于Android支持:设计NavigationView勾选菜单子项的主要内容,如果未能解决你的问题,请参考以下文章
Android支持:设计NavigationView勾选菜单子项
Android 支持设计浮动操作按钮高度对于白色以外的颜色不可见
android:textAllCaps="false" 不适用于 TabLayout 设计支持