Xamarin Android 菜单项未动态显示

Xamarin Android Menu item not show dynamically

我正在使用 Xamarin 开发我的应用程序 Android,我遇到了菜单项问题。 Android 库的更新出现问题 - 所有遗留支持现在都在 AndroidX 库中,所以我将整个项目迁移到它并发生了以下情况。

关闭我的应用程序的用户应该能够登录。登录和注册按钮隐藏后,注销按钮显示。这很好用,但我发现它只是因为弹出 login/register 对话框,它以某种方式强制菜单在对话框关闭时重绘。问题是当用户注销时,分别应该显示登录和注册按钮和隐藏注销按钮,但只有注销隐藏而其他按钮不显示。只有在单击菜单中的某些内容后,它才会重新绘制自身并显示按钮。

都在截图上显示了。

Menu how it looks

login popup dialog

after login

after logout - buttons not shown

这是我操作按钮的方式:

private void SetupGuiAfterSignIn()
    {
        if (!User.IsSignIn())
            return;

        var navheadr = navigationView.GetHeaderView(0).FindViewById<LinearLayout>(Resource.Id.navheader);
        navheadr.Visibility = ViewStates.Visible;

        var navheaderUsername = navigationView.GetHeaderView(0).FindViewById<TextView>(Resource.Id.navheader_username);
        navheaderUsername.Text = User.GetEmail();

        navigationView.Menu.FindItem(Resource.Id.nav_login).SetVisible(false);
        navigationView.Menu.FindItem(Resource.Id.nav_register).SetVisible(false);
        navigationView.Menu.FindItem(Resource.Id.nav_logout).SetVisible(true);

        navigationView.Menu.FindItem(Resource.Id.nav_find_users).SetVisible(true);

        InvalidateOptionsMenu();

    }

private void SetupGuiAfterLogout()
    {
        if (User.IsSignIn())
            return;

        var navheadr = navigationView.GetHeaderView(0).FindViewById<LinearLayout>(Resource.Id.navheader);
        navheadr.Visibility = ViewStates.Gone;

        navigationView.Menu.FindItem(Resource.Id.nav_login).SetVisible(true);
        navigationView.Menu.FindItem(Resource.Id.nav_register).SetVisible(true);
        navigationView.Menu.FindItem(Resource.Id.nav_logout).SetVisible(false);

        navigationView.Menu.FindItem(Resource.Id.nav_find_users).SetVisible(false);


        InvalidateOptionsMenu();

    }

我还有 OnCreateOptionsMenu:

public override bool OnCreateOptionsMenu(IMenu menu)
    {
        navigationView.InflateMenu(Resource.Menu.menu); //Navigation Drawer Layout Menu Creation  
        navigationView.InflateHeaderView(Resource.Menu.NavMenuHeader);
        base.OnCreateOptionsMenu(menu);
        return true;
    }

对于您提供的代码,我认为是由于Login、Register、LoginOut没有设置在同一个组中造成的,如下所示。

    <menu
xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
    <item
android:id="@+id/nav_home"
android:title="Home" />
    <item
android:id="@+id/nav_findusers"
android:visible="false"
android:title="FindUsers" />
    <item
android:id="@+id/nav_import"
android:title="Import" />
    <item
android:id="@+id/nav_FAQ"
android:title="FAQ" />
    <item
android:id="@+id/nav_report"
android:title="ReportBug" />
     
</group>
<item>
    <menu>
        <item
android:id="@+id/nav_Login"
android:title="Login" />
        <item
android:id="@+id/nav_register"
android:title="Register" />
        <item  android:visible="false"
android:id="@+id/nav_LoginOut" 
android:title="LoginOut" />

    </menu>
</item>
</menu>

更新:

你可以使用两个组并设置id来显示分割线

<?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_home"
android:title="Home" />
    <item android:visible="false"
android:id="@+id/nav_findusers"
android:title="FindUsers" />
    <item
  android:id="@+id/nav_import"
android:title="Import" />
    <item
android:id="@+id/nav_FAQ"
android:title="FAQ" />
    <item
android:id="@+id/nav_report"
android:title="ReportBug" />

</group>
<group android:id="@+id/tt" android:checkableBehavior="single">
    <item
android:id="@+id/nav_Login"
android:title="Login" />
    <item
android:id="@+id/nav_register"
android:title="Register" />
    <item  android:visible="false"
android:id="@+id/nav_LoginOut"
android:title="LoginOut" />
</group>
</menu>

菜单外观:

登录后:

注销后:

项目点击时的代码:

  void setupDrawerContent(NavigationView navigationView)
    {
        navigationView.NavigationItemSelected += (sender, e) =>
        {

            switch (e.MenuItem.ItemId)
            {
                case Resource.Id.nav_home:
                    {
                        //drawerLayout.OpenDrawer(Resource.Layout.Home);
                        //var home = new Intent(this, typeof(Activity_Home));
                        //StartActivity(home);
                        //navigationView.Menu.FindItem(Resource.Id.nav_LoginOut).SetVisible(true);
                        break;
                    }

                case Resource.Id.nav_Login:
                    {
                        navigationView.Menu.FindItem(Resource.Id.nav_LoginOut).SetVisible(true);
                        navigationView.Menu.FindItem(Resource.Id.nav_findusers).SetVisible(true);
                        navigationView.Menu.FindItem(Resource.Id.nav_Login).SetVisible(false);
                        navigationView.Menu.FindItem(Resource.Id.nav_register).SetVisible(false);

                        
                        break;
                    }

                case Resource.Id.nav_LoginOut:
                    {
                        navigationView.Menu.FindItem(Resource.Id.nav_Login).SetVisible(true);
                        navigationView.Menu.FindItem(Resource.Id.nav_register).SetVisible(true);
                        navigationView.Menu.FindItem(Resource.Id.nav_LoginOut).SetVisible(false);

                        navigationView.Menu.FindItem(Resource.Id.nav_findusers).SetVisible(false);
                        break;
                    }

                default:
                    break;

                    //TODO check the ID and start your activity or switch the fragments
            }

            //e.MenuItem.SetChecked(true);
            //drawerLayout.CloseDrawers();
        };
    }