【问题标题】:Runtime navigation drawer items运行时导航抽屉项目
【发布时间】:2015-10-07 03:36:34
【问题描述】:

在我的应用程序中,我正在使用以下 .xml 加载导航抽屉。在第一组中,我有一个 current_deviceother_device 的项目。此处可能列出了其他几个设备,但这是在运行时通过 api 调用确定的。有没有办法将项目动态添加到这个.xml?或者更好的方法来做到这一点。 c

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

<group
    android:id="@+id/nav_devices_group"
    android:checkableBehavior="single">

    <item
        android:id="@+id/nav_current_device"
        android:icon="@drawable/common_full_open_on_phone"
        android:title="@string/nav_current_device" />

    <item
        android:id="@+id/nav_other_device"
        android:icon="@drawable/common_full_open_on_phone"
        android:title="@string/nav_devices" />

</group>

<group>
    <item
        android:id="@+id/nav_settings"
        android:icon="@drawable/ic_setting_dark"
        android:title="@string/nav_settings" />

    <item
        android:id="@+id/nav_about"
        android:icon="@android:drawable/ic_dialog_info"
        android:title="@string/nav_about" />
</group>

</menu>

导航抽屉布局如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">

<include
    layout="@layout/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main"
    app:menu="@menu/menu_nav_drawer" />

</android.support.v4.widget.DrawerLayout>

【问题讨论】:

标签: android android-layout navigation-drawer xml-layout


【解决方案1】:

这是添加项目的代码。

mNavigationView = (NavigationView) context.findViewById(R.id.navigationView);
Menu menu = mNavigationView.getMenu();
SubMenu devicesMenu = menu.addSubMenu(Menu.NONE, DEVICES_MENU_ID, Menu.NONE, "Devices");
//You get your deviceId (nexus5Id, nexus6Id and so on) from your API call
//You should see deviceId in your code, from a loop or network callback
//in place of my hardcoded devices ids
devicesMenu.add(DEVICES_MENU_ID, nexus5Id, "Nexus 5");
devicesMenu.add(DEVICES_MENU_ID, nexus6Id, "Nexus 6");
devicesMenu.add(DEVICES_MENU_ID, nexus5XId, "Nexus 5X");
devicesMenu.add(DEVICES_MENU_ID, nexus6PId, "Nexus 6P");

要获取菜单项,将其设置为选中,更改它的图标或任何内容:

MenuItem device = devicesMenu.find(deviceId);
devicesMenu.setChecked(true);

要删除一个项目:

devicesMenu.remove(deviceId);

请注意,SubMenu 扩展了 Menu。我建议你查看MenuMenuItem的文档。

编辑

由于您的 id 不适合 MenuItems 所需的 int 格式,我认为您应该添加一个 ScrollView/NestedScrollView 来代替 NavigationMenu,为非组项目添加带有 drawableLeft 的经典 TextView,以及可扩展视图(例如 LinearLayout)带有 TextView 组,单击时展开,显示包含所有设备的 RecyclerView。

这样,您可以使用自定义适配器并以您想要的方式管理您的 ID(不过,最佳做法是在 RecyclerView(和旧版 ListView)中使用长 ID)。

但是,我不确定在 NavigationDrawer 中添加所有设备(无论是带有菜单的标准 API,还是带有 RecyclerView)是一个好习惯,因为设备可能很长,对吧?对于大型设备集合,我会在 NavigationDrawer 中使用标准的非分组“设备”项,然后向用户显示搜索框或设备列表。

【讨论】:

  • 如果你有nexus5ID,我会使用d2bc6f797fd07614 之类的东西。但是它正在寻找“int itemID”。我可以将实际的设备 ID 转换为 int 吗?
  • 我有这个deviceMenu.add(R.id.nav_devices, Integer.parseInt("d2bc6f797fd07614"), Menu.NONE, "Nexus");,但它导致异常:Caused by: java.lang.NumberFormatException: Invalid int: "d2bc6f797fd07614"
  • 我认为如果你有这样的 id 就不能使用菜单,因为将其转换为字节,并且强制转换可能不适合 int 容量,你需要很长时间,但这会很麻烦,和菜单不支持它
  • 好的,我只是用一个更简单的 int 问题解决了这个问题。我如何将它放在菜单的顶部?现在设备菜单出现在底部,在我的设置下
  • 我对我的答案进行了编辑,但我不知道您的设备收藏是否会很大,请告诉我:)
【解决方案2】:

发件人:How to programmatically add a submenu item to the new material design android support library

向 NavigationView 添加动态菜单目前是设计支持库中的错误我已将其报告给 android 错误源跟踪。所以等到bug修复。但是,如果您想要 临时解决方案,您可以这样做。首先添加您的动态菜单..

    navView = (NavigationView) findViewById(R.id.navView);
    Menu m = navView.getMenu();
    SubMenu topChannelMenu = m.addSubMenu("Top Channels");
    topChannelMenu.add("Foo");
    topChannelMenu.add("Bar");
    topChannelMenu.add("Baz");

添加菜单后,只需编写以下代码..

    MenuItem mi = m.getItem(m.size()-1);
    mi.setTitle(mi.getTitle());

这是目前的 hacky 解决方案。但是为我工作...

【讨论】:

    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    • 2020-12-08
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    相关资源
    最近更新 更多