用户登录时更改 NavigationView 项目

Posted

技术标签:

【中文标题】用户登录时更改 NavigationView 项目【英文标题】:Change NavigationView items when user is logged 【发布时间】:2015-09-04 05:59:00 【问题描述】:

我的应用程序的主要活动有一个导航抽屉,以这种方式在 XML 中实例化:

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_
    android:layout_
    android:layout_gravity="start"
    app:headerLayout="@layout/drawer_header"
    app:menu="@menu/application_drawer"
    android:background="@color/white"/>

现在,导航抽屉的菜单项如下:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
    <item
        android:id="@+id/login"
        android:icon="@drawable/ic_action_person"
        android:title="@string/login"/>
    <item
        android:id="@+id/settings"
        android:icon="@drawable/ic_action_settings"
        android:title="@string/settings"/>
    <item
        android:id="@+id/terms"
        android:icon="@drawable/ic_action_about"
        android:title="@string/terms_and_conditions_menu"/>
    <item
        android:id="@+id/about"
        android:icon="@drawable/ic_action_about"
        android:title="@string/info_hotelsclick"/>
</group>

我想做的是在某些条件下动态更改第一项(可能还有其他项)。例如,一旦用户登录,我想将“登录”条目更改为“注销”;-)

我怎样才能做到这一点?我设法以这种方式将一个项目添加到抽屉中

    Menu menu = navigationView.getMenu();
    menu.add("Test");

但这对我来说听起来不太好,我很确定一定有更清洁的方法。

...但是有吗?

【问题讨论】:

调用方法以更新值再次设置抽屉。 【参考方案1】:

我认为最好的方法是将所有项目包含在菜单中并更改它们的可见性。

<item
    android:id="@+id/login"
    android:icon="@drawable/ic_action_person"
    android:title="@string/login"
    android:visible="true" />

<item
    android:id="@+id/logout"
    android:icon="@drawable/ic_action_person"
    android:title="@string/logout"
    android:visible="false" />

然后

navigationView.getMenu().findItem(R.id.login).setVisible(false);
navigationView.getMenu().findItem(R.id.logout).setVisible(true);

您也可以对整组项目执行此操作

<group
    android:id="@+id/group_1"
    android:checkableBehavior="single"
    android:visible="false">
    ...
</group>

navigationView.getMenu().setGroupVisible(R.id.group_1, true)

【讨论】:

它可以工作,但空间会重新发送,知道如何删除空间吗? 很好的答案!我认为关于 NavigationView 的实用信息很少。 使用 navigationView.getMenu().findItem(R.id.login).setVisibility(View.GONE) 和 setVisibility(View.VISIBLE) 代替,这样不可见的 UI 元素就不会占用空间。跨度> @JoakimSandqvist 写的内容不正确。您不能调用 setVisibility,因为 findItem 不返回视图 为什么删除组或清除在动态更新模式下不起作用。我无法动态删除项目并添加新项目。我的片段应该重新创建以显示。【参考方案2】:

简单的解决方案: 在菜单目录下添加两个xml文件:

    navigation_with_login.xml 登录用户的导航菜单

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <group android:checkableBehavior="single">
            <item
                android:id="@+id/nav_camera"
                android:icon="@drawable/ic_menu_camera"
                android:title="Import" />
            <item
                android:id="@+id/nav_gallery"
                android:icon="@drawable/ic_menu_gallery"
                android:title="Gallery" />
            <item
                android:id="@+id/nav_slideshow"
                android:icon="@drawable/ic_menu_slideshow"
                android:title="Slideshow" />
            <item
                android:id="@+id/nav_login"
                android:icon="@drawable/ic_menu_login"
                android:title="Login" />
        </group>
    
    
    </menu>
    

    navigation_with_logout.xml 默认用户的导航菜单:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <group android:checkableBehavior="single">
            <item
                android:id="@+id/nav_camera"
                android:icon="@drawable/ic_menu_camera"
                android:title="Import" />
            <item
                android:id="@+id/nav_gallery"
                android:icon="@drawable/ic_menu_gallery"
                android:title="Gallery" />
            <item
                android:id="@+id/nav_slideshow"
                android:icon="@drawable/ic_menu_slideshow"
                android:title="Slideshow" />
            <item
                android:id="@+id/nav_logout"
                android:icon="@drawable/ic_menu_logout"
                android:title="Logout" />
        </group>
    
    </menu>
    

现在您可以更改NavigationView 项目,只需编写几行代码。

NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);

if(islogin)
    
        navigationView.getMenu().clear();
        navigationView.inflateMenu(R.menu.navigation_with_login);
     else
    
        navigationView.getMenu().clear();
        navigationView.inflateMenu(R.menu.navigation_with_logout);
    

【讨论】:

这是最好的解决方案! 这对我来说看起来更优雅,特别是考虑到在其他解决方案中隐藏的项目仍然占用空间,显然(我自己没有测试,但 cmets 这么说)。 谢谢若昂·何塞齐尼奥 @manish jain:非常感谢。你解决了我的相关问题,在应用程序中有 2 个抽屉列表用于不同的登录。 不好的方法,如果我需要更改两个项目并且其中一个有 3 个状态怎么办。所以我需要 6 个菜单,哈哈【参考方案3】:

首先获取导航菜单

 NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
Menu menu = navigationView.getMenu();

动态添加菜单

 if(loggedOut)
        menu.add(R.id.submenu_others, R.id.action_logout, Menu.NONE, "logout");

这里是 menu.add(groupId, menuItemId, orderOfMenu, menuItem text)

     if(loggedIn)
        menu.removeItem(R.id.action_logout);

【讨论】:

【参考方案4】:

我搞定了,当你需要更改标题时试试这个:

navigationView.getMenu().findItem(R.id.yourItemId).setTitle("my title");

希望对您有所帮助!

【讨论】:

当然,这也可以,但是我还需要更改相关的操作和图标...我宁愿使用 Lamorak 在下面提供的显示/隐藏解决方案。不管怎样,谢谢你! :-)

以上是关于用户登录时更改 NavigationView 项目的主要内容,如果未能解决你的问题,请参考以下文章

从 Core Data 加载图像使 NavigationView 过渡变得跳跃

DrawerLayout 和 NavigationView 的使用

无法修改 NavigationView 中的 TextView

SwiftUI:如何更改 NavigationView 的色调(背景颜色)?

Exchange-批量取消用户下次登录时必须更改密码

在默认的 ASP.Net MVC 模板中,为啥用户每次更改时都会重新登录?