动态填充项目时的导航抽屉组标题
Navigation Drawer Group Title when Items populated Dynamically
我在我的应用程序中使用标准导航抽屉来显示两种菜单项:
仪表板、详细信息视图等高级常规项目
每个用户帐户的特定屏幕。
第二组项目需要动态填充,即我无法在 XML 中指定它们。我正在努力争取第二组的冠军。
这是我当前的 menu.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="General">
<menu>
<group
android:id="@+id/main_group"
android:orderInCategory="1">
<item
android:id="@+id/nav_dashboard"
android:icon="@drawable/ic_dashboard"
android:title="@string/nav_dashboard"
android:checkable="true"
android:checked="true"/>
<item
android:id="@+id/nav_all"
android:icon="@drawable/ic_list"
android:title="@string/nav_all"
android:checkable="true" />
</group>
</menu>
</item>
<item android:title="Accounts">
<menu>
<group
android:id="@+id/accounts_group"
android:orderInCategory="2">
</group>
</menu>
</item>
</menu>
标题 Accounts
在我的导航抽屉中不可见。但是,如果我不动态填充项目而是在 XML 中放置一些随机项目,它是可见的。
这是我填充菜单项的方式:
for (int index = 0; index < accountsList.size(); index++) {
MainActivityPresenter.AccountInfo accountInfo = accountsList.get(index);
menu.add(R.id.accounts_group, index + MENU_ITEM_ID, 1, accountInfo.name).setCheckable(true);
}
寻找提示。为什么我动态添加项目时项目标题 Accounts
没有显示?谢谢!
首先你需要改变你的菜单 XML 布局,如下所示,这样标题将无法选择,只能检查 sub-items。
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="General"
android:checkable="false"
android:id="@+id/general_menu">
<menu>
<item
android:id="@+id/nav_dashboard"
android:icon="@drawable/ic_dashboard"
android:title="@string/nav_dashboard"/>
<item
android:id="@+id/nav_all"
android:icon="@drawable/ic_list"
android:title="@string/nav_all"/>
</menu>
</item>
<item android:title="Accounts"
android:checkable="false"
android:id="@+id/accounts_group">
<menu>
<!-- filled at runtime -->
</menu>
</item>
</menu>
然后在您的代码中,您需要访问正确的菜单 item
,这对我们来说就像 "logical group",您可以使用此代码来执行此操作:
//use the index of the group, in your case Account item is the 2nd in the
//XML this means its index is 1
val menuItem: MenuItem = navigationView.menu.getItem(1)
//save the generated view Id, because if you need a reference after you need
//to save newSubMenuId property somewhere before adding the item
val newSubMenuId = View.generateViewId()
//add the item to the submenu. The order value it's used to position the
//item inside the group. With 1 it will be the first item, 2 will be the second and so on
val addedItem = menuItem.subMenu.add(Menu.NONE, newSubMenuId, 1, R.string.new_account)
//add a nice icon to the inserted sub-item
addedItem.setIcon(R.drawable.ic_menu_account_icon)
现在你会遇到一个问题,如果你的菜单 XML 中没有 group
,你将无法使用 android:checkableBehavior="single"
属性 来阻止 multi-selection 项 NavigationView
.
要解决最后一个问题,我们可以这样做:
val navigationView: NavigationView = findViewById(R.id.nav_view)
navigationView.setNavigationItemSelectedListener { selectedItem ->
//loop trough all the main items (which are groups for us) to remove the checked state
for (i in 0 until navigationView.menu.size()) {
val menuItem = navigationView.menu.getItem(i)
menuItem.isChecked = false
if (menuItem.hasSubMenu()) {
//if they have a subMenu, loop trough all the subitems
//and remove the checked state from them too
for (z in 0 until menuItem.subMenu.size()) {
val subMenuItem = menuItem.subMenu.getItem(z)
subMenuItem.isChecked = false
}
}
}
// set item as selected to persist highlight
selectedItem.isChecked = true
// close drawer when item is tapped
drawerLayout.closeDrawers()
// Add code here to update the UI based on the item selected
// For example, swap UI fragments here
true
}
所有代码都是用 Kotlin
编写的,但我认为如果您仍然使用它,将它转换为 Java 就不会那么麻烦了。顺便说一句,如果你有问题就问:)
PS: You don't need to specify .setCheckable(true)
when you create a
new item. New items are checkable by default
我在我的应用程序中使用标准导航抽屉来显示两种菜单项:
仪表板、详细信息视图等高级常规项目
每个用户帐户的特定屏幕。
第二组项目需要动态填充,即我无法在 XML 中指定它们。我正在努力争取第二组的冠军。
这是我当前的 menu.xml 文件
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="General">
<menu>
<group
android:id="@+id/main_group"
android:orderInCategory="1">
<item
android:id="@+id/nav_dashboard"
android:icon="@drawable/ic_dashboard"
android:title="@string/nav_dashboard"
android:checkable="true"
android:checked="true"/>
<item
android:id="@+id/nav_all"
android:icon="@drawable/ic_list"
android:title="@string/nav_all"
android:checkable="true" />
</group>
</menu>
</item>
<item android:title="Accounts">
<menu>
<group
android:id="@+id/accounts_group"
android:orderInCategory="2">
</group>
</menu>
</item>
</menu>
标题 Accounts
在我的导航抽屉中不可见。但是,如果我不动态填充项目而是在 XML 中放置一些随机项目,它是可见的。
这是我填充菜单项的方式:
for (int index = 0; index < accountsList.size(); index++) {
MainActivityPresenter.AccountInfo accountInfo = accountsList.get(index);
menu.add(R.id.accounts_group, index + MENU_ITEM_ID, 1, accountInfo.name).setCheckable(true);
}
寻找提示。为什么我动态添加项目时项目标题 Accounts
没有显示?谢谢!
首先你需要改变你的菜单 XML 布局,如下所示,这样标题将无法选择,只能检查 sub-items。
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="General"
android:checkable="false"
android:id="@+id/general_menu">
<menu>
<item
android:id="@+id/nav_dashboard"
android:icon="@drawable/ic_dashboard"
android:title="@string/nav_dashboard"/>
<item
android:id="@+id/nav_all"
android:icon="@drawable/ic_list"
android:title="@string/nav_all"/>
</menu>
</item>
<item android:title="Accounts"
android:checkable="false"
android:id="@+id/accounts_group">
<menu>
<!-- filled at runtime -->
</menu>
</item>
</menu>
然后在您的代码中,您需要访问正确的菜单 item
,这对我们来说就像 "logical group",您可以使用此代码来执行此操作:
//use the index of the group, in your case Account item is the 2nd in the
//XML this means its index is 1
val menuItem: MenuItem = navigationView.menu.getItem(1)
//save the generated view Id, because if you need a reference after you need
//to save newSubMenuId property somewhere before adding the item
val newSubMenuId = View.generateViewId()
//add the item to the submenu. The order value it's used to position the
//item inside the group. With 1 it will be the first item, 2 will be the second and so on
val addedItem = menuItem.subMenu.add(Menu.NONE, newSubMenuId, 1, R.string.new_account)
//add a nice icon to the inserted sub-item
addedItem.setIcon(R.drawable.ic_menu_account_icon)
现在你会遇到一个问题,如果你的菜单 XML 中没有 group
,你将无法使用 android:checkableBehavior="single"
属性 来阻止 multi-selection 项 NavigationView
.
要解决最后一个问题,我们可以这样做:
val navigationView: NavigationView = findViewById(R.id.nav_view)
navigationView.setNavigationItemSelectedListener { selectedItem ->
//loop trough all the main items (which are groups for us) to remove the checked state
for (i in 0 until navigationView.menu.size()) {
val menuItem = navigationView.menu.getItem(i)
menuItem.isChecked = false
if (menuItem.hasSubMenu()) {
//if they have a subMenu, loop trough all the subitems
//and remove the checked state from them too
for (z in 0 until menuItem.subMenu.size()) {
val subMenuItem = menuItem.subMenu.getItem(z)
subMenuItem.isChecked = false
}
}
}
// set item as selected to persist highlight
selectedItem.isChecked = true
// close drawer when item is tapped
drawerLayout.closeDrawers()
// Add code here to update the UI based on the item selected
// For example, swap UI fragments here
true
}
所有代码都是用 Kotlin
编写的,但我认为如果您仍然使用它,将它转换为 Java 就不会那么麻烦了。顺便说一句,如果你有问题就问:)
PS: You don't need to specify
.setCheckable(true)
when you create a new item. New items are checkable by default