I am working on on my app with Xamarin Android and I am having an issue with menu items. Problem appeared with update of Android libraries - all legacy support is now in AndroidX libraries so I migrated the whole project to it and following happened.
User off my application should be able to login. After login and register buttons hide and logout buttons shows. This works well but I found out it is just because of pop up login/register dialog, which somehow force the menu to redraw when the dialog closes. Problem is when user logouts, then respectively should login and register button show and logout button hide but only logout hides and other buttons don't show. Only after clicking to something in the menu it redraw itself and button are shown.
It is all shown on screenshots.
after logout - buttons not shown
There are how I manipulate buttons:
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();
}
I also have 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;
}
For the code you provided, i think it caused by the Login, Register, LoginOut is not set in the same group like below.
<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>
Updated:
You could use two groups and set the id to show the dividing line.
<?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>
Menu how it looks:
After login:
After logout:
The code when the item clicked:
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();
};
}