Change NavigationView items when user is logged - android

My app's main activity has a navigation drawer, instantiated in the XML in this way:
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/application_drawer"
android:background="#color/white"/>
Now, the menu entry for the navigation drawer is the following:
<?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>
What I'd like to do is to change the first item (and possibly the others as well) dynamically under some conditions. For instance, I'd like to change the "Login" entry with a "logout" one once the user has logged in ;-)
How can I achieve that? I managed to add an item to the Drawer in this way
Menu menu = navigationView.getMenu();
menu.add("Test");
but it doesn't sound that good to me, I'm pretty sure there must be a cleaner way.
...but does it?

I thing the best approach to this is to include all your items in the menu and the change their visibility.
<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" />
then
navigationView.getMenu().findItem(R.id.login).setVisible(false);
navigationView.getMenu().findItem(R.id.logout).setVisible(true);
You can also do this with whole groups of items
<group
android:id="#+id/group_1"
android:checkableBehavior="single"
android:visible="false">
...
</group>
and
navigationView.getMenu().setGroupVisible(R.id.group_1, true)

Simple solution:
Add two xml files in menu directory:
navigation_with_login.xml Navigation Menu for logged in users
<?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 Navigation Menu for default user:
<?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>
Now you can change NavigationView items,just write few lines of code.
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);
}

Frst get the navigationmenu
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
Menu menu = navigationView.getMenu();
To add the menu dynamically
if(loggedOut){
menu.add(R.id.submenu_others, R.id.action_logout, Menu.NONE, "logout");
}
Here is menu.add(groupId, menuItemId, orderOfMenu, menuItem text)
if(loggedIn){
menu.removeItem(R.id.action_logout);
}

I got it done, try this when you need to change the title:
navigationView.getMenu().findItem(R.id.yourItemId).setTitle("my title");
Hope it helped!

Related

Menu items get added outside of the group

I have a very nice NavigationView with a menu.
This menu consists of two groups, menu_top and menu_bottom.
Relevant menu XML:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single"
android:id="#+id/menu_top">
<item
android:id="#+id/nav_frontpage"
android:icon="#android:drawable/ic_menu_view"
android:title="#string/menu_home" />
</group>
<group android:checkableBehavior="single"
android:id="#+id/menu_bottom">
<item
android:id="#+id/nav_login"
android:icon="#android:drawable/ic_secure"
android:title="#string/menu_login"
/>
<item
android:id="#+id/nav_register"
android:icon="#android:drawable/ic_menu_view"
android:title="#string/menu_register" />
</group>
</menu>
I try to add multiple items to the menu_top group, but this would not work.
It instead adds it below the menu_bottom group. You can see this because my logout button is in between two lines, so above this button is a group and below this button is a group.
Relevant Java code:
Menu mainMenu = navigationView.getMenu();
for(PageModel page : pages) {
MenuItem pageButton = mainMenu.add(R.id.menu_top,Menu.NONE, Menu.NONE,page.title.rendered);
}
Screenshot:
Try this: android:orderInCategory="999" for the bottom group.
Code will look like this:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single"
android:id="#+id/menu_top">
<item
android:id="#+id/nav_frontpage"
android:icon="#android:drawable/ic_menu_view"
android:title="#string/menu_home" />
</group>
<group android:checkableBehavior="single"
android:id="#+id/menu_bottom"
android:orderInCategory="999">
<item
android:id="#+id/nav_login"
android:icon="#android:drawable/ic_secure"
android:title="#string/menu_login"
/>
<item
android:id="#+id/nav_register"
android:icon="#android:drawable/ic_menu_view"
android:title="#string/menu_register" />
</group>
</menu>

Add items to menu group programatically in navigation view

I am trying to add menu items to menu group pragmatically but I found no way to do that. I am using Navigation View and added below mentioned menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/nav_lang_currency"
android:title="" />
<item
android:id="#+id/nav_home"
android:title="" />
<group android:id="#+id/nav_refer" />
<item
android:id="#+id/nav_setting"
android:title="" />
<item
android:id="#+id/nav_about_us"
android:title="" />
<item
android:id="#+id/nav_logout"
android:title="" />
</menu>
Everything looks good as mentioned.
I just want to add multiple menu items in nav_refer group at run-time as per business requirement but I found no way to do that.
I searched solution on SO but found no way to do that.
Kindly suggest me how to add multiple menu items in group at run-time.
To add menu to a particular group, call this method Menu.add(int groupId, int itemId, int order, CharSequence title)
Menu menu = navigationView.getMenu();
menu.add(R.id.nav_refer, 123, Menu.NONE, "Title1");
menu.add(R.id.nav_refer, 124, Menu.NONE, "Title2");
menu.add(R.id.nav_refer, 125, Menu.NONE, "Title3");
Important : Initially if you have empty group then newly added items will appear in bottom, to solve this you need to mention orders for groups. add a attribute for all your groups android:orderInCategory="101"
You can do something like this:
NavigationView navView = (NavigationView) findViewById(R.id.navView);
Menu menu = navView.getMenu();
SubMenu subMenu = menu.addSubMenu("sub menu");
subMenu.add("item 1");
subMenu.add("item 2");
subMenu.add("item 3");
create res --> menu file new layout
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:checkableBehavior="single">
<item android:title="حساب کاربری">
<menu>
<group android:title="حساب کاربری">
<item android:title="ورود" />
<item android:title="ثبت نام" />
</group>
</menu>
</item>
</group>
<group android:checkableBehavior="single">
<item android:title="سایت">
<menu>
<group android:title="حساب کاربری">
<item android:title="ورود" />
<item android:title="ثبت نام" />
</group>
</menu>
</item>
</group>
</menu>
set NavigationView to app:menu="#menu/drawer_view"
i hope help you

Remove subsection and from navigation drawer submenu

I want to remove the unwanted space created in submenu.
Is there any possibility I can achieve it from menu.xml class?
Here is my navigation_drawer_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/all"
android:checked="true"
android:icon="#drawable/ic_channels"
android:title="All Channels" />
.......
<item
android:id="#+id/other"
android:icon="#drawable/ic_other"
android:title="Others" />
</group>
<item android:title="">
<menu>
<item
android:id="#+id/setting"
android:icon="#drawable/ic_action_settings"
android:title="Settings" />
<item
android:id="#+id/about"
android:icon="#drawable/ic_about"
android:title="About" />
<item
android:id="#+id/share"
android:icon="#drawable/ic_share"
android:title="Share" />
</menu>
</item>
Thanks.
This is how I implement it. Because you are adding a title to a menu it is not recognizing it is empty.
<?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/nav1"
android:checked="true"
android:title="Pos 1" />
<item
android:id="#+id/nav2"
android:title="Pos 2" />
</group>
<group
android:id="#+id/menu_two"
android:checkableBehavior="single">
<item
android:id="#+id/pos3"
android:title="Pos 3" />
<item
android:id="#+id/pos4"
android:title="Pos 4" />
</group>
</menu>
First, please read this Ian Lake's (Android Developer Advocate) answer:
NavigationView seeks to match the material design specs for the
navigation drawer which state an 8dp space between content areas.
Generally there are no ways to override NavigationView to
specifically break the specifications.
From: How I can remove the unnecessary top padding of the Navigation view?
As you see this undesired padding is sub header of your section.
To delete it, you would need to delete this
<item android:title=""> and </item>
To do it you need ****merge** all menu elements** () into single group (no subsections).
After changes your code should look like this:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/all"
android:checked="true"
android:icon="#drawable/ic_channels"
android:title="All Channels" />
.......
<item
android:id="#+id/other"
android:icon="#drawable/ic_other"
android:title="Others" />
<menu>
<item
android:id="#+id/setting"
android:icon="#drawable/ic_action_settings"
android:title="Settings" />
<item
android:id="#+id/about"
android:icon="#drawable/ic_about"
android:title="About" />
<item
android:id="#+id/share"
android:icon="#drawable/ic_share"
android:title="Share" />
<menu>
</group>
Still you can do this: How to create a custom navigation drawer in android
If you have a question, please free to ask
Hope it help
To accomplish this programatically, use the overload:
menu.add(int groupId, int itemId, int order, int titleRes)
(and make sure to provide different groupId's for the different sections)

how can i show android:icon in android menu ( android studio)

i create application with default android studio menu, but when i change default icon with my drawable icon this circle icon is not visible.
my problem is how can i show icon in my android menu.
I used this XML:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<group android:checkableBehavior="single">
<item android:id="#+id/nav_radio" android:icon="#drawable/radio_icon"
android:title="Radio" />
<item android:id="#+id/nav_tv" android:icon="#drawable/tv_icon"
android:title="TV" />
</group>
<item android:title="Autre">
<menu>
<item android:id="#+id/nav_share" android:icon="#drawable/share_icon"
android:title="Share" />
<item android:id="#+id/nav_send" android:icon="#drawable/mail_icon"
android:title="Send" />
<item android:id="#+id/nav_like" android:icon="#drawable/heart_icon"
android:title="Rate Me" />
<item android:id="#+id/nav_recording" android:icon="#drawable/cloud_icon"
android:title="Recording" />
<item android:id="#+id/nav_close" android:icon="#drawable/power_icon"
android:title="Close" />
</menu>
</item>
</menu>
and i don't show icone
please help me
In you activity Where you have used NavigationView use this one line of code. doing this may solve your problem.
setItemIconTintList(null);
in your Activity
mNavigation = (NavigationView) findViewById(R.id.navigation);
mNavigation.setItemIconTintList(null);

How to show/hide submenus inside NavigationView android

I want to create an expandablelistview like view inside navigation drawer where initially only main titles are shown (collapsed submenus). When title is clicked the submenus should appear (if possible animate)
I am using android.support.design.widget.NavigationView. I am able to add submenus via xml.
<group android:checkableBehavior="all">
<item
android:id="#+id/action_venues"
android:title="TITLE 1">
<menu>
<group
android:id="#+id/group1"
android:checkableBehavior="single"
>
<item android:title="SUBTITLE1.1" />
<item android:title="SUBTITLE1.2" />
<item android:title="SUBTITLE1.3" />
</group>
</menu>
</item>
<item
android:id="#+id/action_vendors"
android:title="TITLE2">
<menu>
<group
android:id="#+id/group2"
android:checkableBehavior="single"
android:visible="false">
<item android:title="SUBTITLE2.1" />
<item android:title="SUBTITLE2.2" />
<item android:title="SUBTITLE2.3" />
</group>
</menu>
</item>
But if I keep any group in the xml android:visible="false" it doesn't appear in the drawer.
I also tried programatically showing/hiding the submenu with:
subMenu1.setGroupVisible(R.id.group1,false);
But it just hides the title menu also.
Is it possible with android.support.design.widget.NavigationView or do I have to use a custom view?
Menu menu = navigationView.getMenu();
for (int i = 0; i < menu.size(); i++) {
if (menu.getItem(i).getItemId() != R.id.login){
menu.getItem(i).setVisible(false);
}
}
I managed to show/hide the subtitles by making the titles a separate group. Not sure if this is the right way:
<group>
<item
android:id="#+id/action_venues"
android:title="group1" />
</group>
<group
android:id="#+id/group2"
android:checkableBehavior="single">
<item android:title="SUBTITLE1.1" />
<item android:title="SUBTITLE1.2" />
<item android:title="SUBTITLE1.3" />
</group>
<group>
<item
android:id="#+id/action_vendors"
android:title="group3" />
</group>
<group
android:id="#+id/group4"
android:checkableBehavior="single"
android:visible="false">
<item android:title="SUBTITLE2.1" />
<item android:title="SUBTITLE2.2" />
<item android:title="SUBTITLE2.3" />
</group>
And then in the code:
Menu drawerMenu = drawer.getMenu();
case R.id.action_venues:
drawerMenu.setGroupVisible(R.id.group2,true);
case R.id.action_vendors:
drawerMenu.setGroupVisible(R.id.group4,true);
But still can't animate.
For the group tags I used
navigationView.getMenu().setGroupVisible(false)
For the item tags I used
navigationView.getMenu().findViewById(R.id.id_of_the_item).setVisibility(View.GONE)
All working.
navigationView.getMenu().findItem(R.id.id_of_the_item).setVisible(false)

Categories

Resources