I have problem with item drawer. I want to get view of item drawer, but it's return null.
this is my menu :
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="none">
<item
android:id="#+id/nav_biodata"
android:icon="#drawable/ic_menu_camera"
android:title="Biodata" />
<item
android:id="#+id/nav_kantor_dinas"
android:icon="#drawable/ic_menu_gallery"
android:title="Kantor Dinas" />
<item
android:id="#+id/nav_aktivitas"
android:icon="#drawable/ic_menu_manage"
android:title="Aktivitas" />
<item
android:id="#+id/nav_logout"
android:icon="#drawable/ic_menu_share"
android:title="Logout" />
</group>
</menu>
and this is try getview :
navigationView = (NavigationView) findViewById(R.id.nav_view);
Menu item = navigationView.getMenu();
MenuItem biodata = item.getItem(0);
v_biodata = biodata.getActionView();
v_biodata is null. So how to fix it ? thanks... sorri for my English.
You can get the views of navigation drawer items using this snippet.
NavigationView navigationView = (NavigationView) mDrawerLayout.findViewById(R.id.navigation_view);
View view = navigationView.getTouchables().get(3); //Pass index to get function to get your desired item view.
Related
I want to change the color of the text of an item that groups a menu.
The xml file:
<?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_mi_cuenta"
android:icon="#mipmap/ic_mi_cuenta"
android:title="#string/mi_cuenta" />
</group>
<item android:title="#string/herramientas">
<menu>
<item
android:id="#+id/nav_configuracion"
android:icon="#mipmap/ic_config"
android:title="#string/configuraci_n" />
</menu>
</item>
</menu>
I wnat to change text color of:
<item android:title="#string/herramientas">
As you can see, Herramientas comes out in black and as the background is also black it barely looks. I can not find any property to change it. The color of the item 'Mis datos' and 'Configuración' change it programmatically as follows from an external json file of a server:
colorElegido = getParseColor(json.getString("colorMenuLateral"));
navigationView.setBackgroundColor(colorElegido);
colorElegido = getParseColor(json.getString("colorFuenteMenuLateral"));
ColorStateList colorList = getColorList(colorElegido);
navigationView.setItemTextColor(colorList);
The following code will workout,
menu.xml
<?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_mi_cuenta"
android:icon="#mipmap/ic_mi_cuenta"
android:title="#string/mi_cuenta" />
</group>
<item
android:id="#+id/herramientas"
android:title="#string/herramientas">
<menu>
<item
android:id="#+id/nav_configuracion"
android:icon="#mipmap/ic_config"
android:title="#string/configuraci_n" />
</menu>
</item>
</menu>
Add this in your styles,
<style name="TextAppearance44">
<item name="android:textColor">#FF0000</item>
<item name="android:textSize">20sp</item>
</style>
<style name="NavigationDrawerStyle">
<item name="android:textSize">16sp</item><!-- text size in menu-->
<item name="android:textColor">#880ACE0A</item>
<item name="itemTextColor">#880ACE0A</item>
</style>
And in your activity,
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
Menu menu = navigationView.getMenu();
MenuItem tools= menu.findItem(R.id.herramientas);
SpannableString s = new SpannableString(tools.getTitle());
s.setSpan(new TextAppearanceSpan(this, R.style.TextAppearance44), 0, s.length(), 0);
tools.setTitle(s);
navigationView.setNavigationItemSelectedListener(this);
Change according to you,
And other text color change you can use like in your xml file,
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
style="#style/NavigationDrawerStyle"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
to make a custom popup make an ImageView in toolbar
private ImageView setting;
public void menuOptions() {
PopupMenu popup = new PopupMenu(MainActivity.this, setting);
// Inflating the Popup using xml file
popup.getMenuInflater()
.inflate(R.menu.menu_main, popup.getMenu());
//registering popup with OnMenuItemClickListener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.button1:
return (true);
case R.id.button2:
// block contacts
return (true);
}
return true;
}
});
popup.show(); //showing popup menu
}
on Button click call above function
menuOptions();
in the layout you inflate menu_main.xml, make your desired view.
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.
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.
I have this menu structure for my navigation view:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_clients"
android:icon="#drawable/ic_group"
android:title="#string/nav_clients"/>
<item
android:id="#+id/nav_products"
android:icon="#drawable/ic_box"
android:title="#string/nav_products" />
<item
android:id="#+id/nav_orders"
android:icon="#drawable/ic_buy"
android:title="#string/nav_orders" />
</group>
<item android:title="#string/nav_title_app">
<menu>
<item
android:id="#+id/nav_settings"
android:icon="#drawable/ic_settings_black"
android:title="#string/nav_settings" />
<item
android:id="#+id/nav_sync"
android:icon="#drawable/ic_sync_black"
android:title="#string/nav_sync" />
</menu>
</item>
I have succeeded to change the menu items text size, but only the item which contains a menu didn't changed the size?
Any ideas?
I haven't found any official way of doing so, neither by style, but you can achieve it programmatically, take a look below.
private void setMenuHeadTitleSize(int itemId) {
Menu menu = mNavigationView.getMenu();
MenuItem menuItem = menu.findItem(itemId);
MenuItem subMenuItem = menuItem.getSubMenu().getItem();
String title = String.valueOf(subMenuItem.getTitle());
SpannableString mNewTitle = new SpannableString(title);
mNewTitle.setSpan(new RelativeSizeSpan(1.1f), 0, title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
subMenuItem.setTitle(mNewTitle);
}
Also give an Id to your SubMenu item
<item android:id="#+id/nav_top"
android:title="#string/nav_title_app">
<menu>
<item
android:id="#+id/nav_settings"
android:icon="#drawable/ic_settings_black"
android:title="#string/nav_settings" />
<item
android:id="#+id/nav_sync"
android:icon="#drawable/ic_sync_black"
android:title="#string/nav_sync" />
</menu>
</item>
and finally, once NavigationView is inflated, and the menu attached, call the function above
setMenuHeadTitleSize(R.id.nav_top);
I wonder if anyone is having problems when redefining the background of the items on a NavigationView with app:itemBackground"? I get the behavior shown on the screenshot, no matter what item I press the last item shows the ripple instead.
Here is my drawer_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single" android:id="#+id/first_group">
<item
android:id="#+id/nav_home"
android:icon="#drawable/ic_home"
android:title="#string/nav_home" />
</group>
<group android:id="#+id/second_group">
<item
android:id="#+id/nav_settings"
android:title="#string/nav_settings" />
<item
android:id="#+id/nav_about"
android:title="#string/nav_about" />
<item
android:id="#+id/nav_logout"
android:title="#string/nav_logout" />
</group>
</menu>
My my_ripple.xml:
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#ffff0000">
<item
android:id="#android:id/mask"
android:drawable="#android:color/white" />
</ripple>
My NavigationView:
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#android:color/white"
app:headerLayout="#layout/drawer_header"
app:itemBackground="#drawable/my_ripple"
app:itemIconTint="#color/drawer_item"
app:itemTextColor="#color/drawer_item"
app:menu="#menu/drawer_menu" />
Possible workaround for now - Just for people looking and just in case....
Adding addOnGlobalLayoutListener in onCreate for the navigation view and applying the Drawable on each menu item.
/**
* Contains the {#link MenuItem} views in the {#link NavigationView}
*/
private final ArrayList<View> mMenuItems = new ArrayList<>(5);
// Grab the NavigationView Menu
final Menu navMenu = mNavigationView.getMenu();
mNavigationView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// Remember to remove the installed OnGlobalLayoutListener
mNavigationView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
// Loop through and find each MenuItem View
for (int i = 0, length = 5; i < length; i++) {
final MenuItem item = navMenu.getItem(i);
mNavigationView.findViewsWithText(mMenuItems, item.getTitle(), View.FIND_VIEWS_WITH_TEXT);
}
// Loop through each MenuItem View and apply your custom Typeface
for (final View menuItem : mMenuItems) {
//Create RippleDrawable called myRipple
((TextView) menuItem).setBackground(myRipple);
}
}
});
Ripple drawables should be defined like this sample:
<!-- A red ripple masked against an opaque rectangle. -->
<ripple android:color="#ffff0000">
<item android:id="#android:id/mask"
android:drawable="#android:color/white" />
</ripple>
read more
https://developer.android.com/reference/android/graphics/drawable/RippleDrawable.html
Apply the itemBackground attribute to the menu rather than the NavigationView. The ripple will then stay contained to the menu item handling the touch event.