Add menu Item in a group dynamically android navigation menu - android

I have a navigation menu which looks like this -
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/nav_home"
android:icon="#drawable/ic_home"
android:title="Home" />
<item
android:id="#+id/nav_logout"
android:icon="#drawable/ic_logout"
android:title="Logout" />
<item
android:id="#+id/choose_bus"
android:title="Choose a bus">
<menu>
<group
android:id="#+id/group_select_bus"
android:checkableBehavior="single">
<!--<item-->
<!--android:id="#+id/menu_option1"-->
<!--android:title="Bus 1" />-->
<!--<item-->
<!--android:id="#+id/menu_option2"-->
<!--android:title="Bus 2" />-->
</group>
</menu>
</item>
I want to add menu_option1 and menu_option2 dynamically from the activity. I tried this but nothing adding -
#Override
public boolean onNavigationItemSelected(MenuItem item) {
NavigationView navView = (NavigationView) findViewById(R.id.nav_view);
Menu menu = navView.getMenu();
MenuItem item1 = menu.getItem(2);
SubMenu subMenu = item1.getSubMenu();
subMenu.add("Bus 1");
subMenu.add("Bus 2");
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}

Try some thing like this
Menu menu = navView.getMenu();
menu.add(R.id.group_select_bus,Menu.NONE,Menu.NONE,Youritem);

Try this:
MenuItem item = mNavigationView.getMenu().getItem(2);
item.getSubMenu().add(R.id.group_select_bus, id, Menu.NONE, "Youritem");

Another approach is to add all items in navigation menu and then change their visibility on specific activity or fragment, like
MenuItem item = mNavigationView.getMenu().getItem(5);
item.setVisible(false);

Seems a little late to answer. There is workaround/hack for this. No need to add list. Just add this little line above your code. It surely works.
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.candidates -> {
binding.navSideView.post {
navSideView.menu.findItem(R.id.candidateManagement).isVisible = !navSideView.menu.findItem(R.id.candidateManagement).isVisible
}
}
}
return true
}
You need to add navigationview.post Runnable before changing visibility. It will update the menu. It works with group too. :)

Related

NavigationView menu's .add not working except in main bodies of onCreate() and onResume()

This is the code of onNavigationItemSelcted
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Menu eventMenu = mNavigationView.getMenu();
eventMenu.add(R.id.events,Menu.NONE,1,"newEvent").setIcon(R.drawable.hangouts_white);
// extra code
}
However, I can perfectly use this add method in onCreate() and onResume(). But, again, if I use this method in onClick() in onCreate() or onResume(), it does not work. As long as it is in their main body, it will work.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNavigationView = findViewById(R.id.navigation_view);
drawerAndToggle();//For drawerlayout setup
Menu eventMenu = mNavigationView.getMenu();
MenuItem eventItem = eventMenu.findItem(R.id.add_custom_event);
eventItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
// This gets executed but does not do anything
eventMenu.add(R.id.events,Menu.NONE,1,"New item");
return true;
}
});
// This one works fine
eventMenu.add(R.id.events,Menu.NONE,1,"New item");
}
But I need to add an item if the user selects "Add Item" which is one of the menu items in the Navigation Drawer. What am I missing or what should I be adding?
Here is my nav_menu XML of my navigation view
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="#+id/events">
<item
android:orderInCategory="1"
android:id="#+id/item1"
android:title="Item 1" />
<item
android:orderInCategory="1"
android:id="#+id/item2"
android:title="Item 2" />
</group>
<group android:id="#+id/settings">
<item
android:orderInCategory="2"
android:id="#+id/add_item"
android:title="Add Item"/>
</group>
</menu>

How to show SearchView from Toolbar only in one Fragment?

In my app i have one activity with two fragment, the app has a toolbar with search action, that search action must be visible only in the second fragment.
So how could i hide the search button and show it only when i'm in fragment2?
My menu.xml looks like this:
<menu 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"
tools:context="it.gabtamagnini.visualstock.MainActivity">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
<item
android:id="#+id/app_bar_search"
android:icon="#drawable/ic_search_black_24dp"
android:title="#string/cerca"
app:showAsAction="ifRoom|withText"
app:actionViewClass="android.widget.SearchView" />
</menu>
I'm using kotlin
In your second fragment:
#Override
public void onPrepareOptionsMenu(Menu menu) {
MenuItem item = menu.findItem(R.id.app_bar_search);
if(item != null)
{
item.setVisible(false);
}
}
I solved by adding the following code in my onViewCreated
setHasOptionsMenu(true)
And i had to override the onPrepareOptionsMenu like this:
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
val item: MenuItem = menu.findItem(R.id.app_bar_search)
item.isVisible = true
}

Adding long press to dynamically generated menu items

Okay, so I have a dynamic menu (In my navigation drawer), generated like so:
In my Main.java onCreate():
DatabaseManager databaseAccess = DatabaseManager.getInstance(this);
databaseAccess.open();
List<String> folders = databaseAccess.getFolders();
databaseAccess.close();
// Set up the menu items
setupMenu(folders);
This gets the headings into an array called 'folders', then runs the setupMenu function:
private void setupMenu(List<String> folders) {
// Sets up the menu
Log.i("Folder Size",String.valueOf(folders.size()));
NavigationView navView = findViewById(R.id.nav_view);
Menu menu = navView.getMenu();
int x = 0;
while(x < folders.size()) {
menu.add(R.id.myfolders,Menu.NONE,Menu.NONE,folders.get(x++));
}
navView.invalidate();
}
Which adds it to the id:myfolders in activity_main_drawer:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<item android:title="My Folders"
android:orderInCategory="1"
android:id="#+id/myfolders">
<menu></menu>
</item>
<item android:checkableBehavior="single" android:orderInCategory="2">
<menu android:id="#+id/about_menu">
<item android:id="#+id/system_about"
android:title="About"
android:icon="#drawable/ic_info" />
</menu>
</item>
</menu>
This all works perfectly, however I want to add longpress functionality to my menu items. I have no idea how to go about doing this, can anyone help?
You get a MenuItem from menu.add() then you can call:
menuItem.getActionView().setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
return false; // true
}
});
But not before you set action view: menuItem.setActionView(new ImageButton(this)).

onNavigationItemSelected not working in NavigationView

Please can someone help me with fragments from the navigation drawer, for some reason I can't get them to work and all the code looks right.
Here is the link to the source code.
Use this code:
navigationView = (NavigationView) findViewById(R.id.navigationView);
navigationView.bringToFront();
Have a look at your MainActivity.java.
You have implemented the callbacks for NavigationView.OnNavigationItemSelectedListener in MainActivity as below,
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// blah blah
}
Also check the setupDrawerContent method.
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setChecked(true);
drawerLayout.closeDrawers();
return true;
}
});
}
In this method you are creating a local OnNavigationItemSelectedListener.
So you are not using the OnNavigationItemSelectedListener that you have overridden in MainActivity.
The solution is to use this as argument for setNavigationItemSelectedListener. By doing this all your clicks will go the onNavigationItemSelected of MainActivity rather than going to the local onNavigationItemSelected.
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(this);
}
Also move the code in the local onNavigationItemSelected to the onNavigationItemSelected of MainActivity.
So your onNavigationItemSelected will be something like this,
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// Handle navigation view item clicks here.
int id = menuItem.getItemId();
menuItem.setChecked(true);
drawerLayout.closeDrawers();
if (id == R.id.nav_home) {
// Handle the home action
Toast.makeText(this, "Home", Toast.LENGTH_SHORT).show();
} else if (id == R.id.nav_the_wetlands) {
Toast.makeText(this, "The Wetlands", Toast.LENGTH_SHORT).show();
TheWetlandsFragment theWetlandsFragment = new TheWetlandsFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.relativelayout_for_fragment, theWetlandsFragment, theWetlandsFragment.getTag()).commit();
} else if (id == R.id.nav_the_mistbelt_forests) {
Toast.makeText(this, "The Mistbelt Forests", Toast.LENGTH_SHORT).show();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Also change your activity_main_drawer_view.xml as follows to solve the multiple selection issue you have in the Navigation Drawer,
<?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:icon="#drawable/ic_dashboard"
android:title="Home" />
</group>
<item android:title="Information">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_the_wetlands"
android:icon="#drawable/ic_event"
android:title="The Wetlands" />
<item
android:id="#+id/nav_the_mistbelt_forests"
android:icon="#drawable/ic_event"
android:title="The Mistbelt Forests" />
<item
android:id="#+id/nav_the_grasslands"
android:icon="#drawable/ic_event"
android:title="The Grasslands" />
</group>
</item>
<item android:title="Quick Go To">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_accommodation"
android:icon="#drawable/ic_event"
android:title="Accommodation" />
<item
android:id="#+id/nav_cuisine"
android:icon="#drawable/ic_forum"
android:title="Cuisine" />
<item
android:id="#+id/nav_leisure_activites"
android:icon="#drawable/ic_forum"
android:title="Leisure & Activites" />
<item
android:id="#+id/nav_agri_tourism"
android:icon="#drawable/ic_forum"
android:title="Agri-tourism" />
<item
android:id="#+id/nav_education"
android:icon="#drawable/ic_forum"
android:title="Education" />
<item
android:id="#+id/nav_arts_crafts_decor"
android:icon="#drawable/ic_forum"
android:title="Arts, Crafts & DeCor" />
<item
android:id="#+id/nav_selective_shopping"
android:icon="#drawable/ic_forum"
android:title="Selective Shopping" />
<item
android:id="#+id/nav_for_children"
android:icon="#drawable/ic_forum"
android:title="For Children" />
</group>
</item>
<item android:title="Midlands Animals">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_midlands_birding_checklist"
android:icon="#drawable/ic_dashboard"
android:title="Midlands Birding Checklist" />
<item
android:id="#+id/nav_midlands_mammals_checklist"
android:icon="#drawable/ic_dashboard"
android:title="Midlands Mammals Checklist" />
</group>
</item>
</menu>
Good luck.
Don't use
NavigationUI.setupWithNavController(navigationView, navController);
instead of it do this
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Toast.makeText(MainActivity.this, "clicked", Toast.LENGTH_SHORT).show();
return false;
}
});
I have also faced the same problem some time back, and at the end i realized that i have not wrote the 2nd line of the following code
navigationView = (NavigationView) findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(this);
you make sure you have written the same otherwise your listener will not work
in my case i forgot to initialize navigation menu.
kindly follow following code:
public void initSideMenu() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
happy coding...
Make sure you have implement the interface NavigationView.OnNavigationItemSelectedListener.
Second point make sure to add these lines otherwise listnere will not be called.
navigationView=(NavigationView) findviewbyid(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(this);
Add this line
navigationView.bringToFront();
Its works for me

I can't get multiple items to appear as selected in Navigation Drawer for Android

I'm building an Android app for the local bus system and I'm trying to use the navigation drawer to act as a filter for the routes that appear on the map. The functionality is there, but I'm struggling with the UI. Whenever I click on an item, everything else is set as unchecked, which is not what I want. I've been trying to find a solution for this issue, but didn't come up with anything. Here is the code for the navigation drawer:
MainActivity:
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// listen for navigation events
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// set up the hamburger icon to open and close the drawer
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
#Override
public boolean onNavigationItemSelected(final MenuItem menuItem) {
final boolean enable;
//update highlighted item in the navigation menu
//menuItem.setChecked(!menuItem.isChecked());
if(menuItem.isChecked()){
menuItem.setChecked(false);
enable = false;
}
else{
menuItem.setChecked(true);
enable=true;
}
//menuItem.setChecked(true);
mNavItemId = menuItem.getItemId();
// allow some time after closing the drawer before performing real navigation
// so the user can see what is happening
// mDrawerLayout.closeDrawer(GravityCompat.START);
mDrawerActionHandler.postDelayed(new Runnable() {
#Override
public void run() {
navigate(menuItem.getItemId(),enable);
}
}, DRAWER_CLOSE_DELAY_MS);
return true;
}
and the layout file:
<item
android:id="#+id/filter_routes"
android:title="#string/filter">
<menu>
<group android:checkableBehavior="all">
<item
android:id="#+id/red_route"
android:title="#string/red_route"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:icon="#drawable/abc_btn_check_material"
android:checked="true"
android:checkable="true"/>
<item
android:id="#+id/blue_route"
android:title="#string/blue_route"
android:icon="#drawable/abc_btn_check_material"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:checked="true"
android:checkable="true"/>
<item
android:id="#+id/green_route"
android:title="#string/green_route"
android:icon="#drawable/abc_btn_check_material"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:checked="true"
android:checkable="true"/>
<item
android:id="#+id/orange_route"
android:title="#string/orange_route"
android:icon="#drawable/abc_btn_check_material"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:checked="true"
android:checkable="true"/>
<item
android:id="#+id/brown_route"
android:title="#string/brown_route"
android:icon="#drawable/abc_btn_check_material"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:checked="true"
android:checkable="true"/>
</group>
</menu>
</item>
I got multiple selections to work by returning false from onNavigationItemSelected(). From the Google docs for this return value of onNavigationItemSelected():
boolean true to display the item as the selected item
Apparently, this means that returning false leaves item selection in your control.
Here's an example.
XML:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="All">
<menu>
<group
android:checkableBehavior="all"
android:id="#+id/checkable_group"
>
<item
android:id="#+id/checkable_item_1"
android:title="A" />
<item
android:id="#+id/checkable_item_2"
android:title="B" />
<item
android:id="#+id/checkable_item_3"
android:title="C" />
<item
android:id="#+id/checkable_item_4"
android:title="D" />
</group>
</menu>
</item>
</menu>
Code:
#Override
public boolean onNavigationItemSelected(MenuItem item) {
if (item.isChecked()) {
item.setChecked(false);
}
else {
item.setChecked(true);
}
return false; // VERY Important to return false here
}
I submitted a bug report about this and it was closed as working as intended. Google apparently made NavigationView use menu XML with no intention of having it work like a menu.

Categories

Resources