I am trying to implement Sidebar NavigationDrawer in my Android project.
To do so, I have used NavigationView in DrawerLayout. To show items I used menu.
I want to add click event on that added menu items.
Code for reference:
In navigation menu -
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/nav_account" android:title="My Account"/>
<item android:id="#+id/nav_settings" android:title="Settings"/>
<item android:id="#+id/nav_layout" android:title="Log Out"/>
</menu>
In View:
<android.support.design.widget.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:menu="#menu/navigation_menu"
android:layout_gravity="start" />
Implement the listener in your Activity:
public class HomeActivity extends AppCompatActivity implements
NavigationView.OnNavigationItemSelectedListener
setNavigationItemSelectedListener in onCreate of Activity
NavigationView mNavigationView = (NavigationView) findViewById(R.id.account_navigation_view);
if (mNavigationView != null) {
mNavigationView.setNavigationItemSelectedListener(this);
}
Override the method
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_account) {
// DO your stuff
}
}
I wanted to make sure the Solution from Nizam can be found in Kotlin to, since it is takeing bigger place every day:
val mDrawerLayout = this.findViewById(R.id.drawer_layout) as DrawerLayout
val mNavigationView = findViewById<View>(R.id.navigation) as NavigationView
Handle the navigation items in onCreate like this:
mNavigationView.setNavigationItemSelectedListener { it: MenuItem ->
when (it.itemId) {
R.id.nav_item1 -> doThis()
R.id.nav_item2-> doThat()
else -> {
true
}
}
}
Remember: Return Type has to be a boolean!
You have to use OnNavigationItemSelectedListener(MenuItem item) method.
for more check this documentation.
Here is a Java 8 approach with smaller boilerplate (no "implements" on Activity). Also helpful if your class is abstract and you don't want to implement this functionality in every other child:
#Override
protected void onCreate(
Bundle savedInstanceState) {
NavigationView navigationView =
findViewById(
R.id.navigationView);
navigationView.setNavigationItemSelectedListener(
MyActivity::onNavigationItemSelected);
}
public static boolean onNavigationItemSelected(MenuItem item) {
if (item.getId() == R.id.my_item) {
myItemClickHandler();
}
return false;
}
Related
Actually I m using navigation drawer but on back button menu item is not visible while the respective fragment is opened.How to set the visibility of menu item?Can anyone help me?
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
Fragment fragment = null;
int id = item.getItemId();
navigationView.getMenu().getItem(0).setActionView(R.layout.menu_home);
navigationView.getMenu().getItem(1).setActionView(R.layout.menu_profile);
navigationView.getMenu().getItem(2).setActionView(R.layout.menu_history);
navigationView.getMenu().getItem(3).setActionView(R.layout.menu_contact_igrab);
navigationView.getMenu().getItem(4).setActionView(R.layout.menu_help);
navigationView.getMenu().getItem(5).setActionView(R.layout.menu_logout);
if (id == R.id.home) {
item.setActionView(R.layout.menu_home_blue);
changeFragments(new CustomerHomeFragment());
} else if (id == R.id.my_profile) {
item.setActionView(R.layout.menu_my_profile_blue);
changeFragments(new CustomerProfileFragment()); } DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
You can make use of setUserVisibleHint method. Override the method and check if isVisibleToUser parameter is true and getActivity() is not null.
Use setChecked() method for set selection navigation item.
make method in your activity:
public void setNavigation(int id) {
navigationView.getMenu().getItem(id).setChecked(true);
}
now call this method in your fragment for navigation item selection :
((YourActivity)mContext).setNavigation(int position);
Hope it will help you!!
First set visiblity false of all the item like :
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_dashboard"
android:icon="#drawable/ic_dashboard"
android:title="#string/nav_dashboard"
android:visible="false" />
</group>
</menu>
Now in Activity you can show and hide item like this.
NavigationView navigationView = (NavigationView)findViewById(R.id.nav_view);
Menu menu =navigationView.getMenu();
MenuItem nav_dashboard = menu.findItem(R.id.nav_dashboard);
nav_dashboard.setVisible(true);
I have a "menu" resource "menu_test" with the following code:
<?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"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".TestActivity" >
<item android:id="#+id/hideshow"
android:title="Body visbility"
android:orderInCategory="100"
android:icon="#drawable/showicon"
app:showAsAction="always" />
</menu>
In my activity.java I inflate the toolbar in the "onCreate" function and add a click listener:
private Toolbar toolbar;
...
toolbar = (Toolbar)findViewById(R.id.toolbarId);
toolbar.inflateMenu(R.menu.menu_test);
toolbar.setOnMenuItemClickListener(this);
I would like to get the ID of "hideshow" and change the icon:
testItem = (MenuItem) toolbar.findViewById(R.id.hideshow);
testItem.setIcon(R.drawable.hideicon);
However to app crashes when getting the ID in the first line. In the click listener function it works fine, since the ID is provided internally with the click:
public boolean onMenuItemClick(MenuItem item)
item.setIcon(R.drawable.hideicon);
So how can I change the icon within the onCreate function? ("findItem" does not work, since toolbar is not a menu)
I may be easier to add the menu items programmatically so you can maintain a reference to them:
public class MainActivity extends AppCompatActivity {
private static final int MENU_SETTINGS = Menu.FIRST;
MenuItem menuItem;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menuItem = menu.add(0, MENU_SETTINGS, 0, R.string.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_SETTINGS:
// DO SOMETHING
break;
}
return super.onOptionsItemSelected(item);
}
}
As the other answers and comments indicate, one needs a reference from onCreateOptionsMenu or onPrepareOptionsMenu.
In my case, this would require a lot of code rewrite, as this is an old project, where everything is based on using toolbars instead of menus.
However, I found an easy solution:
Instead of finding the ID and changing the icon, I created several instances of menu_test[1 .. n].xml with different icons and simply use inflateMenu(R.menu.menu_test[1 .. n]) depending on the icon I need.
If you write new code, use the solution from Abtin Gramian, so I mark that as the proper answer.
I have an app with a NavigationView and two tabs a and b. Two MenuItems in the NavigationView correspond to tab a and b so that, when tab a is selected, NavigationView MenuItem A should be selected, and the same for MenuItem B. Selecting MenuItem A and B should also change tab to a and b correspondingly. Selected here means changing the colors of the icon and text using a selector like this:
colors_navigationview.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true"
android:color="#color/red"
android:drawable="#color/red" />
<item android:state_checked="false"
android:color="#color/gray"
android:drawable="#color/gray" />
</selector>
NavigationView definition in layout:
<android.support.design.widget.NavigationView
android:id="#+id/my_navigationview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/my_navigationview_header"
app:menu="#menu/my_navigationview"
app:itemIconTint="#drawable/colors_navigationview"
app:itemTextColor="#drawable/colors_navigationview"
/>
The MenuItems are contained in a SubMenu, defined like this:
my_navigationview.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/navigation_menu"
android:title="#string/foo">
<menu>
<item
android:id="#+id/my_navigationview_tab1"
android:icon="#drawable/fooicon"
android:title="#string/bar"/>
<item
android:id="#+id/my_navigationview_tab2"
android:icon="#drawable/baricon"
android:title="#string/barg"/>
</menu>
</item>
</menu>
The problem is that, when selecting tab a or b, be it by clicking the tabs directly or swiping the ViewPager for the tabs, the MenuItems A and Bs colors are not updated. Selecting the MenuItems directly in the NavigationView works, however, and the exact same code is called. Thus I am a bit baffled as to why this does not work.
To summarize:
Selecting a MenuItem in the NavigationView sets the correct color and changes tab. Everything is ok.
Selecting a tab changes the tab, but the selection color is not changed. I think the MenuItem is set to selected, since MenuItem.setSelected(true) is called.
What can I try to fix this issue? I am currently at a loss - this should be an easy thing to do IMO. I have tried the following and more:
Various suggestions from this question.
Invalidating various GUI elements, also the NavigationView and DrawerLayout.
Relevant methods in my Activity
#Override
public void onCreate()
{
// ...
// mTabLayout and mViewPager are created properly.
mTabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager)
{
#Override
public void onTabSelected(TabLayout.Tab tab)
{
super.onTabSelected(tab);
updateNavigationViewSelection();
}
});
}
#Override
public void onResume()
{
// ...
// To set correct NavigationView when resuming. Actually works ok at startup.
updateNavigationViewSelection();
}
public void updateNavigationViewSelection()
{
int currentItem = mViewPager.getCurrentItem();
selectNavigationMenuItem(currentItem);
}
public void selectNavigationMenuItem(int tab)
{
MenuItem menuItem = null;
NavigationView navigationView = (NavigationView) findViewById(R.id.my_navigationview);
switch (tab)
{
case TAB1:
menuItem = getNavigationMenuItemTab1();
break;
case TAB2:
menuItem = getNavigationMenuItemTab2();
break;
}
if (menuItem != null)
{
unselectAllNavigationMenuItems(); // Calls setChecked(false) on all MenuItems, may be commented out for testing.
// We arrive here, from onTabSelected(), onResume() and onNavigationItemSelected().
// onResume() sets the color correctly, as does onNavigationItemSelected(),
// but *not* when calling from onTabSelected(). All the values seem to be correct, but nothing happens.
// It seems that checked is set to true, but there is some invalidation missing.
// Invalidating NavigationView or DrawerLayout does nothing.
menuItem.setChecked(true);
}
}
#Override
public boolean onNavigationItemSelected(MenuItem menuItem)
{
switch (menuItem.getItemId())
{
case R.id.my_navigationview_tab1:
selectNavigationMenuItem(TAB1);
// Close drawer.
return true;
case R.id.my_navigationview_tab2:
selectNavigationMenuItem(TAB2);
// Close drawer.
return true;
default:
return false;
}
}
#Nullable
private MenuItem getNavigationMenuItemTab1()
{
MenuItem navigationMenu = getNavigationMenu();
return navigationMenu == null ? null : navigationMenu.getSubMenu().findItem(R.id.my_navigationview_tab1);
}
#Nullable
private MenuItem getNavigationMenuItemTab2()
{
MenuItem navigationMenu = getNavigationMenu();
return navigationMenu == null ? null : navigationMenu.getSubMenu().findItem(R.id.my_navigationview_tab2);
}
#Nullable
private MenuItem getNavigationMenu()
{
NavigationView navigationView = (NavigationView) findViewById(R.id.my_navigationview);
return navigationView == null ? null : navigationView.getMenu().findItem(R.id.navigation_menu);
}
private void unselectAllNavigationMenuItems()
{
MenuItem item;
item = getNavigationMenuItemTab1();
if (item != null)
item.setChecked(false);
item = getNavigationMenuItemTab2();
if (item != null)
item.setChecked(false);
}
Seems like i found a little workaround.
Several methods in like :
navigationView.getMenu().getItem(indx).setChecked(true);
navigationView.getMenu().findItem(someId).setChecked(true);
navigationView.setCheckedItem(someId);
navigationView.getMenu().performIdentifierAction(someId, 2);
did not work. But if you trigger the event by calling the navigation listener
onNavigationItemSelected(MenuItem)
method it works.
e.g. in your app:
onNavigationItemSelected(getNavigationMenuItemTab1());
I have a problem with dynamically (programmatically) created submenu in navigation drawer when rotating the menu. My navigation view menu xml contains only main menu (see below). Submenu is added when onCreate event is called. Everything works fine until I rotate the screen - the only displayed thing from a submenu is its label. I tried to investigate the problem and also tried with static variables, but with no success.
Can you tell me what's wrong with my code?
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single" android:id="#+id/main_group">
<item
android:id="#+id/leagues_in_progress_item"
android:icon="#drawable/ic_format_line_spacing_black_48dp"
android:title="#string/title_activity_leagues_in_progress" />
<item
android:id="#+id/last_matches_item"
android:icon="#drawable/ic_access_alarm_black_48dp"
android:title="#string/title_activity_last_matches" />
<item
android:id="#+id/archive_item"
android:icon="#drawable/ic_folder_open_black_48dp"
android:title="#string/title_activity_archive" />
<item
android:id="#+id/put_score_item"
android:icon="#drawable/ic_add_circle_outline_black_48dp"
android:title="#string/title_activity_put_score" />
</group>
</menu>
HomeActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.pinokio);
this.mDrawerLayout = (DrawerLayout) findViewById(R.id.pinokioLayout);
// enabling action bar app icon and behaving it as toggle button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
this.mDrawerToggle = new ActionBarDrawerToggle(this, this.mDrawerLayout, R.string.app_name, R.string.app_name);
this.mDrawerLayout.setDrawerListener(this.mDrawerToggle);
HomeActivity.mNavigationView = (NavigationView) findViewById(R.id.left_drawer);
this.addLeaguesSubmenu();
HomeActivity.mNavigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
displayMenuFragment(menuItem);
return true;
}
});
if (savedInstanceState == null) {
this.displayMenuFragment(HomeActivity.mNavigationView.getMenu().getItem(0));
}
}
/**
* Add submenu that contains leagues in progress
* #return HomeActivity
*/
private void addLeaguesSubmenu()
{
if (this.internetConnection.isOnline()) {
if (HomeActivity.menuLeagues == null) {
Intent intent = this.getIntent();
HomeActivity.menuLeagues = intent.getParcelableArrayListExtra("leagues");
}
this.leaguesSubmenu.generate(HomeActivity.mNavigationView, HomeActivity.menuLeagues);
}
}
And that's the method generating a submenu:
#Override
public void generate(NavigationView navigationView, ArrayList<League> leagues)
{
Menu menu = navigationView.getMenu();
SubMenu leaguesSubMenu = menu.addSubMenu(this.context.getResources().getString(R.string.title_activity_leagues_in_progress));
League league;
MenuItem menuItem;
for (int i = 0; i<leagues.size(); i++) {
league = leagues.get(i);
menuItem = leaguesSubMenu.add(league.getShortName());
Intent intent = new Intent();
intent.putExtra("leagueId", league.getId());
menuItem.setIntent(intent);
if (!league.getFoosballMode()) {
menuItem.setIcon(R.drawable.ic_fifa);
}
else {
menuItem.setIcon(R.drawable.ic_foosball);
}
}
}
I believe this is probably because when rotated the View gets reinflated but your generation code is in onCreate, so you have two options if thats the case. You can re-generate the menu when the view gets reinflated or add this to your Activity in your AndroidManifest.xml file:
android:configChanges="orientation|screenSize"
Also if your interesting refer to here for information on handling configuration changes such as rotation: http://developer.android.com/guide/topics/resources/runtime-changes.html
How to Call an Activity while using Side Navigation in Android.
I am using this sample :Navigation menu for Android (based off Google+ app)
https://github.com/darvds/RibbonMenu
Here i want, whenever user will click on Home then need to call CategoryActivity and when do click on Home2 then need to call OptionsActivity and so on.....
RibbonsampleActivity.Java:
public class RibbonsampleActivity extends Activity implements iRibbonMenuCallback {
/** Called when the activity is first created. */
private RibbonMenuView rbmView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
rbmView = (RibbonMenuView) findViewById(R.id.ribbonMenuView1);
rbmView.setMenuClickCallback(this);
rbmView.setMenuItems(R.menu.ribbon_menu);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
rbmView.toggleMenu();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
#Override
public void RibbonMenuItemClick(int itemId) {
// Handle item selection
}
}
ribbon_menu.xml:
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/ribbon_menu_home" android:title="Home" android:icon="#drawable/ic_launcher"></item>
<item android:id="#+id/ribbon_menu_home2" android:title="Home2" android:icon="#drawable/ic_launcher"></item>
<item android:id="#+id/ribbon_menu_home3" android:title="Home3" android:icon="#drawable/ic_launcher"></item>
I want to call activities by using particular Side Bar Navigation Item:
Home > CategroyActivity
Home2 > OptionsActivity
Home3 > ArrowActivity
you have got a null pointer in getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar() returns null. there could be couple of reasons for this, most probably this could be an issue of your project setup. check your AndroidManifest.xml and remove if you have set a "fullscreen" or "no title bar" theme.
I was facing the same issue. Solution for this problem is you need to use Fragment instead of Activity.
Best Example here: http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/