I have implemented navigation drawer, it is working fine. The only problem that I have to make selected item to deselect when the navigationdrawer closes. I wonder how could I able to get the index value of selected menu item.
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setChecked(false);
}
)}
One way to do is store menu item ID in variable e.g checkedItemID
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItemID=menuItem.getItemId();
}
)}
Then on implement
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
// Do whatever you want here
navigationView.getMenu().findItem(menuItemID).setChecked(false);
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
// Do whatever you want here
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
Make a variable position of int datatype. Firstly set its value to 0 and onNavigationItemSelected change its value to menuItem index(like 0 or 1 or 2 and so on).Now this position will provide you the index of selected menuItem.
int position = 0;
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.first:
position = 0;
break;
case R.id.second:
position = 1;
break;
case R.id.third:
position = 2;
break;
}
return true;
}
});
Try this to get navigation item at position 0 getItem(index) will give you desired item
navigationView.getMenu().getItem(selectedposition).setChecked(false);
also use this link for reference for getting seleted item http://thegeekyland.blogspot.in/2015/11/navigation-drawer-how-set-selected-item.html
use below code for getting selected position
int selectedposition= 0;
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.firstitemid:
selectedposition= 0;
break;
case R.id.seconditemid:
selectedposition= 1;
break;
case R.id.thirditemid:
selectedposition= 2;
break;
}
return true;
}
});
Another easy way that worked for me
public boolean onNavigationItemSelected(MenuItem item) {
int index = (item.getItemId() % item.getGroupId())-1;
....
}
I think, this would be much more efficient than using For loop or Switch case.
If you still have problems then my suggestion would be to check your Item Id and group Id in Log-cat so that you would have a better understanding of what you are dealing with.
This is all you need, it deselects and selects the new one
navigationView.setCheckedItem(item.getItemId());
And it should go at the bottom of onNavigationItemSelected.
To make it more clear here's an example
#Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_home:
controller.setFragment(new HomeFragment());
break;
case R.id.nav_settings:
controller.setFragment(new SettingsFragment());
break;
case R.id.nav_logout:
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.putExtra(autoLogin, false);
startActivity(intent);
break;
}
navigationView.setCheckedItem(item.getItemId());
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return false;
}
First assign your navigationMenu to a class field
private NavigationView navigationView;
private int currentPosition;
...
navigationView = (NavigationView) findViewById(R.id.nav_view);
Now in the menu callback you can loop over the menu items :
public boolean onNavigationItemSelected(MenuItem item) {
for (int i=0;i<navigationView.getMenu().size();i++){
if(item==navigationView.getMenu().getItem(i)){
currentPosition=i;
break;
}
}
....
}
You can change the order of the menu items without breaking anything
Related
here i used basic navigation view provided by android studio
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.getMenu().getItem(1).setChecked(true);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
/* // Handle navigation view item clicks here.
int id = item.getItemId();*/
//Check and un-check menu item if they are checkable behaviour
switch (item.getItemId()) {
case R.id.nav_camera: {
Intent intent = new Intent(MainActivity.this, TabbedActivity.class);
startActivity(intent);
break;
}
case R.id.nav_gallery: {
Toast.makeText(getApplicationContext(), "youclicked", Toast.LENGTH_SHORT).show();
break;
}
/* else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}*/
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
});
even though i'm checking the second item it was responding to clicks how to stop that
please help me i'm facing this problem since yesterday
You can do this in onPrepareOptionsMenu(Menu menu)
#Override
public boolean onPrepareOptionsMenu (Menu menu){
super.onPrepareOptionsMenu(menu);
MenuItem myItem = menu.findItem(R.id.myId); //here your menu ids
myItem.setEnabled(false);
return true;
}
Prepare the Screen's standard options menu to be displayed. This is
called right before the menu is shown, every time it is shown. You can
use this method to efficiently enable/disable items or otherwise
dynamically modify the contents.
Comment these id's which one you don't want to click like this :-
case R.id.nav_camera: {
Intent intent = new Intent(MainActivity.this, TabbedActivity.class);
startActivity(intent);
break;
}
case R.id.nav_gallery: {
Toast.makeText(getApplicationContext(), "youclicked", Toast.LENGTH_SHORT).show();
break;
}
This way you can check the last item and the current item is the same or not
private int prevId = -1;
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (prevId == -1 || prevId != id) {
// Do event handling on each item.
}
// ...
}
I used BottomNavigationView to switch fragments. How to get currently selected menu item, to prevent reopening fragment ?
BottomNavigationView bottomNavigationView = (BottomNavigationView)
findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_1:
// open fragment 1
break;
case R.id.action_2:
// open fragment 2
break;
case R.id.action_3:
// open fragment 3
break;
}
return false;
}
});
}
Get selected item at first and then getMenu().findItem(int itemId)
bottomNavigationView.getMenu().findItem(bottomNavigationView.getSelectedItemId())
Solution:
private int getSelectedItem(BottomNavigationView bottomNavigationView) {
Menu menu = bottomNavigationView.getMenu();
for (int i = 0; i < bottomNavigationView.getMenu().size(); i++) {
MenuItem menuItem = menu.getItem(i);
if (menuItem.isChecked()) {
return menuItem.getItemId();
}
}
return 0;
}
Get the currently selected menu item ID using getSelectedItemId:
int selectedItemId = bottomNavigationView.getSelectedItemId();
MenuItem selectedItem = bottomNavigationView.getMenu().findItem(selectedItemId);
This method started being available from Android Support Library 25.3.0.
I think the simplest solution for checking if the previous item is the next item is this:
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
final int previousItem = bottomNavigationView.getSelectedItemId();
final int nextItem = item.getItemId();
if (previousItem != nextItem) {
switch (nextItem) {
case R.id.action_1:
// open fragment 1
break;
case R.id.action_2:
// open fragment 2
break;
case R.id.action_3:
// open fragment 3
break;
}
}
return true;
}
}
);
Note that there is no need for iterating, and that onNavigationItemSelected returns true, because the function consumes the event.
I hope it helps someone.
In my app, I used navigation drawer. Here I listed all the items.
From the image,the items are,
Home
Filter & Sort
WishList
Shop
MyOrder
Settings
LogOut
If I am in the Fragment of Shop , I need to hide it. How to do this?
Please help me.
You can handle it in fragments onAttach method. Set the visibility of perticular item according to your need.
#Override
public void onAttach(Context context) {
super.onAttach(context);
YourActivity activity = (YourActivity)context;
NavigationView navigationView = (NavigationView) activity.findViewById(R.id.yournavigationviewid);
navigationView.getMenu().findItem(R.id.youritemid).setVisible(false);
}
inside your setNavigationItemSelectedListener where you get the selected menuItem, you can implement the code. Also you require to store the instance of the hidden menu item to make it visible later
MenuItem prevMenuItem;
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
if(prevMenuItem != null) prevMenuItem.setVisible(true) //making visible the previously hidden item.
menuItem.setVisible(false);
prevMenuItem = menuItem //storing the instance of currently hidden item to make it visible later.
return true;
}
});
In your public onNavigationItemSelected(MenuItem item) if you are setting one fragment then automatically drawer will hide. I'm doing like this :
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
toolbar.setTitle(item.toString());
int id = item.getItemId();
if (id == R.id.dashboard) {
fragment = new DashboardFragment();
} else if (id == R.id.manage_users) {
}else{
}
setFragmentLayout(fragment);
return true;
}
Set your fragment according to your requirements.
You can hide the drawer using mDrawerLayout.closeDrawers() in onNavigationItemSelected Listener like this:
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setChecked(true);
switch (menuItem.getItemId()) {
case R.id.navigation_item_shop:
//do your stuffs or attach fragment
mDrawerLayout.closeDrawers();
return true;
default:
return true;
}
}
}
on the fragments overide the onAttach method. Set the visibility of for items your don't need.
#Override
public void onAttach(Context context) {
super.onAttach(context);
MainActivity activity = (MainActivity)context;
NavigationView navigationView = (NavigationView) activity.findViewById(R.id.navmenu);
// hide the menu items not related to this fragment
Menu m = navigationView.getMenu();
m.findItem(R.id.first).setVisible(false);
m.findItem(R.id.second).setVisible(false);
m.findItem(R.id.therd).setVisible(false);
//and so on
}
I have created MainActivity with NavigationView. When Activity is opened I want to automatically select the first item in the navigation drawer and open Fragment under that item. I've searched a lot but didn't find any proper solutions.
What is the proper way to do this ?
Main Activity:
public class MainActivity extends AppCompatActivity implements Config {
private NavigationView navigationView;
private DrawerLayout drawerLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitleTextColor(getResources().getColor(R.color.colorIcons));
if (null != getSupportActionBar())
getSupportActionBar().setLogo(R.drawable.ic_blogger_white);
//Start PostListFragmentWebView
/*PostListFragmentWebView postListFragmentWebView = new PostListFragmentWebView();
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame, postListFragmentWebView)
.commit();*/
//Initializing NavigationView
navigationView = (NavigationView) findViewById(R.id.navigationView);
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Checking if the item is in checked state or not, if not set it to checked state.
if (menuItem.isChecked()) menuItem.setChecked(false);
else menuItem.setChecked(true);
//Closing drawer on item click
drawerLayout.closeDrawers();
//Check to see which item was clicked and perform the appropriate action.
switch (menuItem.getItemId()) {
case R.id.posts:
PostListFragmentWebView postListFragment = new PostListFragmentWebView();
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame, postListFragment)
.commit();
return true;
case R.id.pages:
PageListFragmentWebView pagetListFragment = new PageListFragmentWebView();
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame, pagetListFragment)
.commit();
return true;
case R.id.blog:
BlogInfoFragmentWebView blogInfoFragment = new BlogInfoFragmentWebView();
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame, blogInfoFragment)
.commit();
return true;
default:
Toast.makeText(getApplicationContext(), getResources().getString(R.string.drawer_error), Toast.LENGTH_SHORT).show();
return true;
}
}
});
// Initializing Drawer Layout and ActionBarToggle
drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_drawer, R.string.close_drawer) {
#Override
public void onDrawerClosed(View drawerView) {
// Code here will be triggered once the drawer closes as we don't want anything to happen so we leave this blank.
super.onDrawerClosed(drawerView);
}
#Override
public void onDrawerOpened(View drawerView) {
// Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank.
super.onDrawerOpened(drawerView);
}
};
//Setting the actionbarToggle to drawer layout
drawerLayout.setDrawerListener(actionBarDrawerToggle);
drawerLayout.getChildAt(0).setSelected(true);
//calling sync state is necessary or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
}
}
In onCreate(), following code will load the first item's fragment upon first start:
if (savedInstanceState == null) {
navigationView.getMenu().performIdentifierAction(R.id.posts, 0);
}
Thanks to calvinfly for this comment.
Add android:checked="true" to your first menu item.
And manually select one item, using
getSupportFragmentManager().beginTransaction().replace(R.id.frame, postListFragment).commit();
to open fragment.
Instead of normal listener ...
navView.setNavigationItemSelected(new Navigation.View.OnNavigationItemSelectedListener() {bla, bla, bla})
Create the listener as an Obj:
NavigationView.OnNavigationItemSelectedListener navViewListener;
navView.setNavigationItemSelectedListener(navViewListener = new NavigationView.OnNavigationItemSelectedListener() {bla, bla, bla})
...and use the Obj to trigger the listener event:
navViewListener.onNavigationItemSelected(navView.getMenu().getItem(0));
...where getItem(0) is the first menu item.
Use a method getItem(0).setChecked(true) or android:checked="true" at its menu item XML definition.
You could also use navigationView.setCheckedItem(R.id.default)(javadoc) after you setup your navigationview.
just add this code in onCreate method:
FragmentTransaction ftrans = getFragmentManager().beginTransaction();
ftrans.replace(R.id.container, <yourfragment>).commit();
Work for me !
This can be done even better while considering orientation and other configuration changes. We could select whatever nav drawer menuitem depending on whether we are coming from a previous state. Check: For the Navigation drawer wielding Activity:-
public static final String SELECTED_NAV_MENU_KEY = "selected_nav_menu_key";
// The selected grid position
private int mSelectedNavMenuIndex = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
...........................................................
navigationView.setNavigationItemSelectedListener(this);
if (savedInstanceState != null) {
// Recover assets
mSelectedNavMenuIndex = savedInstanceState.getInt(SELECTED_NAV_MENU_KEY);
// Recover menu as selected
MenuItem menuItem = navigationView.getMenu().getItem(mSelectedNavMenuIndex);
toggleNavMenuItemCheck(menuItem);
navigationView.getMenu().performIdentifierAction(menuItem.getItemId(), mSelectedNavMenuIndex);
return;
} else {
MenuItem menuItem = navigationView.getMenu().getItem(mSelectedNavMenuIndex);
toggleNavMenuItemCheck(menuItem);
navigationView.getMenu().performIdentifierAction(menuItem.getItemId(), mSelectedNavMenuIndex);
}
}
The toggle method that helps uncheck or check the menu item
private void toggleNavMenuItemCheck(MenuItem menuItem) {
if (menuItem.isChecked()){
menuItem.setChecked(false);
} else {
menuItem.setChecked(true);
}
}
This is how I save the state of the selected menu item. Check:-
#Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.nav_explore:
showExploreFragment(null);
mSelectedNavMenuIndex = 0;
break;
case R.id.nav_orders:
mSelectedNavMenuIndex = 1;
break;
case R.id.nav_settings:
mSelectedNavMenuIndex = 2;
break;
default:
showExploreFragment(null);
mSelectedNavMenuIndex = 0;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
// Save any important data for recovery
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(SELECTED_NAV_MENU_KEY, mSelectedNavMenuIndex);
}
NB: The line with code:
navigationView.getMenu().performIdentifierAction(menuItem.getItemId(), mSelectedNavMenuIndex);
Can be replaced by the code:
onNavigationItemSelected(menuItem);
in menu.xml remember to mention android:checkable="true" for single item and android:checkableBehavior="single" for a group of items.
<item
android:id="#+id/pos_item_help"
android:checkable="true"
android:title="Help" />
<group
android:id="#+id/group"
android:checkableBehavior="single">
<item
android:id="#+id/menu_nav_home"
android:icon="#drawable/ic_home_black_24dp"
android:title="#string/menu_nav_home" />
</group>
then inside NavigationItemSelectedListener use setCheckedItem(R.id.item_id_in_menu) to make it selected.
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.pos_item_pos:
navigationView.setCheckedItem(R.id.pos_item_pos);
break;
case R.id.pos_item_orders:
navigationView.setCheckedItem(R.id.pos_item_orders);
break;
default:
}
return true;
}
And you do not have to do the dirty task of managing the selected item anymore. navigationView manages it by self.
1.) To land to the HomeFragment initially, use this inside your onCreate() in MainActivity:
Fragment fragment = new HomeFragment();
// replacing the fragment
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
}
2.) To set the item as selected in navigationDrawer set the item as checked in navigation_menu.xml
android:checked = "true"
How can i set ActionBarDrawerToggle at right corner ? because i set listview gravity
android:layout_gravity="end"
so i want ActionBarDrawerToggle to be at right , How can i do that ??
this is my code
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout,R.drawable.ic_drawer,R.string.drawer_open,R.string.drawer_close)
{
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu();
}
};
I can't do this using the click on "home" icon, and I think this wouldn't be good because drawer will appear in the right side. But, as #runamok, I want to have an option menu item (as opposed to replacing the "home" icon which normally performs "back" functionality) on the right side which triggers the drawer to transition in/out from the right.
Besides using android:layout_gravity="right", use an option menu item to perform the open/close movement.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.my_menu_item:
if(!mDrawerLayout.isDrawerOpen(Gravity.RIGHT))
mDrawerLayout.openDrawer(Gravity.RIGHT);
else
mDrawerLayout.closeDrawer(Gravity.RIGHT);
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
}
ANSWER
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.my_menu_item:
if(!mDrawerLayout.isDrawerOpen(GravityCompat.END))
mDrawerLayout.openDrawer(GravityCompat.END);
else
mDrawerLayout.closeDrawer(GravityCompat.END);
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
}
Try adding this line to android manifest file:
android:supportsRtl="true"