NavigationView items not checking - android

In my NavigationView, I have most of my items divided into sections with subheaders. I'm achieving this by putting a menu inside an item:
<?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/drawer_top"
android:title="#string/top"/>
<item
android:id="#+id/drawer_header"
android:title="#string/header1">
<menu>
<item
android:id="#+id/drawer_item1"
android:title="#string/item1"/>
<item
android:id="#+id/drawer_item2"
android:title="#string/item2"/>
</menu>
</item>
</group>
</menu>
However, this leads to the first item, drawer_top, being eternally checked. Other items are not checkable. My onNavigationItemSelected-Code looks like this:
#Override
public boolean onNavigationItemSelected(final MenuItem menuItem) {
menuItem.setChecked(true);
... (navigate)
return true;
}

It seems that submenus are not checkable by design.
Here is a workaround:
mNavigationView.getMenu().clear();
mNavigationView.inflateMenu(R.menu.menu_drawer);
mNavigationView.getMenu().findItem(mNavItemId).setChecked(true);

Related

How can i get android toolbar menu group

In some pages of stackoverflow said that you can get menu goup with menu.findItem(R.id.groupId) but always return null and i want to know how can i get menu group
<?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:id="#+id/fdp_m_group_normal">
<item android:id="#+id/fdp_m_today"
app:actionLayout="#layout/menu_today"
app:showAsAction="always|withText"
android:orderInCategory="100"
android:title="today"/>
<item android:id="#+id/fdp_m_tomorrow"
app:actionLayout="#layout/menu_tomorrow"
app:showAsAction="always|withText"
android:orderInCategory="101"
android:title="tomorrow"/>
<item android:id="#+id/fdp_m_after"
app:actionLayout="#layout/menu_after"
app:showAsAction="always|withText"
android:orderInCategory="102"
android:title="after"/>
</group>
<group android:id="#+id/fdp_m_group_range">
<item android:id="#+id/fdp_m_plus1"
app:actionLayout="#layout/menu_plus1"
app:showAsAction="always|withText"
android:orderInCategory="103"
android:title="+1"/>
<item android:id="#+id/fdp_m_plus2"
app:actionLayout="#layout/menu_plus2"
app:showAsAction="always|withText"
android:orderInCategory="104"
android:title="+2"/>
<item android:id="#+id/fdp_m_plus3"
app:actionLayout="#layout/menu_plus3"
app:showAsAction="always|withText"
android:orderInCategory="105"
android:title="+3"/>
</group>
</menu>
and my java code for accessing menu
#Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fdp_menu, menu);
// Below line always return null
MenuItem mGroupOne = menu.findItem(R.id.fdp_m_group_normal);
super.onCreateOptionsMenu(menu, inflater);
}
Getting group using findItem does return null. I am assuming you only need it for visibility. Try using menu.setGroupVisible(R.id,false);
menu.findItem will return null if there is no item in 'menu' with the id.
So first of all check that 'menu' is the right menu to be looking in, and then check in menu.xml that you have declared an item with the correct id.

Navigation View selecting multiple items

I implemented the Navigation View (Support Library 24.0.0):
But a strange behavior occurred in which i have been trying to control since.
Here is my drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="Categories">
<menu>
<group android:checkableBehavior="single">
<item
android:id="#+id/navigation_item_1"
android:icon="#drawable/ic_news"
android:title="Top Stories" />
<item
android:id="#+id/navigation_item_2"
android:icon="#drawable/ic_music"
android:title="Entertainment" />
<item
android:id="#+id/navigation_item_3"
android:icon="#drawable/ic_sport"
android:title="Sport" />
<item
android:id="#+id/navigation_item_4"
android:icon="#drawable/ic_lifestyle"
android:title="Lifestyle" />
<item
android:id="#+id/navigation_item_5"
android:icon="#drawable/ic_tech"
android:title="Technology" />
<item
android:id="#+id/navigation_item_6"
android:icon="#drawable/ic_world"
android:title="International" />
</group>
</menu>
</item>
</menu>
But the result is :
in which only one should be selected.
I solved it using :
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem item) {
for (int i = 0; i < 6; i++) {
MenuItem top = navigationView.getMenu().getItem(0).getSubMenu().getItem(i);
if (top.isChecked()) top.setChecked(false);
}
return true;
}
});
Unchecking all items in the menu
return true, that checks the clicked item.

Is a scollable TextSelectionMenu possible?

It seems impossible to find any answer on my question/problem regarding af scollable TextSelectionMenu! I have searched the whole Stackoverflow and Google without any succes and I have tried various ideas out.
I have 10 menu items in my custom TextSelectionMenu. Only 6 of them is visible, the rest is of course not, since you can't scroll to the others. Is it possible to implement a Scrollview/HorizontalListview of any sort to be able to scroll to the rest?
My menu_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<item
android:id="#+id/textcolor"
android:icon="#drawable/textcolor"
android:showAsAction="always"
android:visible="true"
android:title="ColorPicker"
tools:ignore="AppCompatResource" />
<item
android:id="#+id/bold"
android:icon="#drawable/bold2"
android:showAsAction="always"
android:visible="true"
android:title="Bold"
tools:ignore="AppCompatResource" />
<item
android:visible="true"
android:id="#+id/italic"
android:icon="#drawable/italic2"
android:showAsAction="always"
android:title="Italic"
tools:ignore="AppCompatResource" />
<item
android:visible="true"
android:id="#+id/underline"
android:icon="#drawable/underline2"
android:showAsAction="always"
android:title="Underline"
tools:ignore="AppCompatResource" />
<item
android:visible="true"
android:id="#+id/stroke"
android:icon="#drawable/strike"
android:showAsAction="always"
android:title="Strikethrough"
tools:ignore="AppCompatResource" />
<item
android:visible="true"
android:id="#+id/increase"
android:icon="#drawable/increase"
android:showAsAction="always"
android:title="Increase"
tools:ignore="AppCompatResource" />
<item
android:visible="true"
android:id="#+id/decrease"
android:icon="#drawable/decrease"
android:showAsAction="always"
android:title="Decrease"
tools:ignore="AppCompatResource" />
The CustomTextSelectionMenu class:
public class CustomTextSelectionMenu extends FragmentActivity implements android.view.ActionMode.Callback {
EditText editText = (EditText) findViewById(R.id.edittext);
#Override
public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
menu.removeItem(android.R.id.selectAll);
menu.removeItem(android.R.id.paste);
return true;
}
#Override
public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
return true;
}
#Override
public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
// Just a lot of switch cases inside here...
return true;
}
}
I think, there is no way to scroll the text selection menu.
But you can do is, show the few menu items say 2 or 3 as showAsAction="always" and the rest of the menu items are automatically can be shown in overflow menu.

How to set default checked item in NavigationView?

When I click on the NavigationView item its selection color changes. But I don't know how to check the first element by default.
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
return true;
}
});
}
add this
android:checked="true"
to your first item in the drawer menu. For example take a look at mine:
<?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/drawer_home"
android:checked="true" //default set to check
android:icon="#drawable/ic_action_home"
android:title="#string/home"/>
<item
android:id="#+id/drawer_favourite"
android:icon="#drawable/ic_action_favorite_black"
android:title="#string/favourite"/>
<item
android:id="#+id/drawer_recent"
android:icon="#drawable/ic_action_recent"
android:title="#string/recent"/>
<item
android:id="#+id/drawer_settings"
android:icon="#drawable/ic_action_settings"
android:title="#string/settings"/>
</group>

Android adding a submenu to a menuItem, where is addSubMenu()?

I want to add a submenu inside my OptionsMenu to a menuItem, programatically according to my parameters. I've checked "MenuItem" in android sdk and there is no addSubMenu() method!, although you can find "hasSubMenu()" and "getSubMenu".
Was thinking on doing this in onCreateOptionsMenu:
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem mi = menu.getItem(MYITEMID); // << this is defined in my XML optionsMenu
SubMenu subm = mi.addSubMenu(0,1,0,"Map 1"); // no addSubMenu() method!!!???
....
How do I create a submenu inside a menuitem in code?
Sometimes Android weirdness is really amazing (and amusing..). I solved it this way:
a) Define in XML a submenu placeholder like this:
<item android:visible="true" android:id="#+id/m_area"
android:titleCondensed="Areas"
android:title="Areas"
android:icon="#drawable/restaur"
android:enabled="true">
<menu>
<item android:id="#+id/item1" android:title="Placeholder"></item>
</menu>
</item>
b) Get sub menu item in OnCreateOptionsMenu, clear it and add my submenu items, like this:
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mapoptions, menu);
int idx=0;
SubMenu subm = menu.getItem(MYITEM_INDEX).getSubMenu(); // get my MenuItem with placeholder submenu
subm.clear(); // delete place holder
while(true)
{
anarea = m_areas.GetArea(idx); // get a new area, return null if no more areas
if(anarea == null)
break;
subm.add(0, SUBAREASID+idx, idx, anarea.GetName()); // id is idx+ my constant
++idx;
}
}
I know this is an old question, but I just came across this problem myself.
The most straightforward way of doing this, seems to be to simply specify the item itself as a submenu, then add to this item.
E.g.:
menu.add(groupId, MENU_VIEW, Menu.NONE, getText(R.string.menu_view));
menu.add(groupId, MENU_EDIT, Menu.NONE, getText(R.string.menu_edit));
SubMenu sub=menu.addSubMenu(groupId, MENU_SORT, Menu.NONE, getText(R.string.menu_sort));
sub.add(groupId, MENU_SORT_BY_NAME, Menu.NONE, getText(R.string.menu_sort_by_name));
sub.add(groupId, MENU_SORT_BY_ADDRESS, Menu.NONE, getText(R.string.menu_sort_by_address));
:
:
Here's a complete answer which builds on the idea of using a placeholder but uses mostly xml to add the submenu.
If you have a menu like so called main_menu.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="My Menu"
android:id="#+id/my_menu_item">
<!-- A empty SubMenu -->
<menu></menu>
</item>
</menu>
Create another menu sub_menu.xml which will be used in my_menu_item:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="SubMenu One"
android:id="#+id/submenu_one" />
<item android:title="SubMenu Two"
android:id="#+id/submenu_two" />
<item android:title="SubMenu Three"
android:id="#+id/submenu_three" />
</menu>
In your onCreateOptionsMenu:
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate your main_menu into the menu
getMenuInflater().inflate(R.menu.main_menu, menu);
// Find the menuItem to add your SubMenu
MenuItem myMenuItem = menu.findItem(R.id.my_menu_item);
// Inflating the sub_menu menu this way, will add its menu items
// to the empty SubMenu you created in the xml
getMenuInflater().inflate(R.menu.sub_menu, myMenuItem.getSubMenu());
}
This solution is nice since the inflater handles most of the work.
The best way to do this is in your xml menu file. You can do this by creating a new menu object inside of an item:
<menu>
<item>
...
<menu>
...
</menu>
...
</item>
</menu>
To provide a comprehensive example of Phil's answer, here is my complete, working XML for a menu with two choices, each of which is a menu with three choices. I intend to add a third menu to the top level ...
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:HTMLCode="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/Examine"
android:title="#string/Examine"
HTMLCode:showAsAction="always">
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:HTMLCode="http://schemas.android.com/apk/res-auto" >
<item android:id="#+id/load"
android:title="#string/load"
HTMLCode:showAsAction="ifRoom|withText" />
<item android:id="#+id/findfirst"
android:title="#string/findfirst"
HTMLCode:showAsAction="ifRoom|withText" />
<item android:id="#+id/findnext"
android:title="#string/FindNext"
HTMLCode:showAsAction="ifRoom|withText" />
</menu>
</item>
<item android:id="#+id/Redirect"
android:title="#string/Redirect"
HTMLCode:showAsAction="ifRoom|withText">
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:HTMLCode="http://schemas.android.com/apk/res-auto" >
<item android:id="#+id/getRedirect"
android:title="#string/getRedirect"
HTMLCode:showAsAction="ifRoom|withText" />
<item android:id="#+id/toggleRedirect"
android:title="#string/toggleRedirect"
HTMLCode:showAsAction="ifRoom|withText" />
<item android:id="#+id/copyRedirect"
android:title="#string/copyRedirect"
HTMLCode:showAsAction="ifRoom|withText" />
</menu>
</item>
</menu>
You should consider use a ActionProvider instead.
public class MyActionProvider extends ActionProvider {
private Context mContext;
public MyActionProvider(Context context) {
super(context);
mContext = context;
}
#Override
public View onCreateActionView() {
//LayoutInflater layoutInflater = LayoutInflater.from(mContext);
return null;
}
#Override
public void onPrepareSubMenu(SubMenu subMenu) {
super.onPrepareSubMenu(subMenu);
subMenu.clear();
subMenu.add("menu 1");
subMenu.add("menu 2");
subMenu.add("menu 3");
}
#Override
public boolean hasSubMenu() {
return true;
}
#Override
public boolean onPerformDefaultAction() {
return super.onPerformDefaultAction();
}
}
I would just create the submenu in xml file, and in run time get the submenu from menu object, (using findItem(id) method) and use submenu.setVisible(boolean) to add/remove it on run time.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu1" android:alphabeticShortcut="a"
android:title="Menu No. 1" android:orderInCategory="1" />
<item android:id="#+id/menu2" android:alphabeticShortcut="b"
android:title="Menu No. 2" android:orderInCategory="2">
<menu >
<group android:id="#+id/group2" android:checkableBehavior="single">
<item android:id="#+id/submenu1" android:title="SubMenu No. 1" />
<item android:id="#+id/submenu2" android:title="SubMenu No. 2" />
</group>
</menu>
</item>

Categories

Resources