I have a double-drawer layout set up and am trying to handle selecting items inside the drawers. The way I have it set up though, I can see that neither onNavigationItemSelected nor onOptionsItemSelected is getting called when I tap something on the menu (I put a log statement right inside the functions). I'm also not totally clear which of those functions should be called.
EDIT: It looks like onOptionsItemSelected() is being called after all, but whichever item I click on, I always get the same id. So maybe it's only allowing me to click some other layer?
There are a lot of other questions similar to this, but none of the answers have been helpful to me. I'd appreciate any insight you may have.
Here is the relevant code inside my onCreate() function in MainActivity.java:
// Adding Toolbar to Main screen
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView leftNavigationView = (NavigationView) findViewById(R.id.notifications_view);
leftNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem item) {
Log.i("left", "left"); // this is never called
// Handle left navigation view item clicks here
int id = item.getItemId();
switch(id) {
case R.id.emerg_con_menuitem:
break;
case R.id.ride_hist_menuitem:
Log.i("I'm hit", "I'm hit");
intent = new Intent(MainActivity.this, loc_report.class); // The action I want to happen when this menu item is tapped
MainActivity.this.startActivity(intent);
break;
case R.id.settings_menuitem:
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
});
NavigationView rightNavigationView = (NavigationView) findViewById(R.id.nav_view);
rightNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem item) {
Log.i("right", "right"); // this is also never called
// Handle Right navigation view item clicks here.
int id = item.getItemId();
Log.i("I am firing", "I am firing");
switch(id) {
case R.id.emerg_con_menuitem:
break;
case R.id.ride_hist_menuitem:
Log.i("I'm hit navigation", "I'm hit navigation");
intent = new Intent(MainActivity.this, loc_report.class);
MainActivity.this.startActivity(intent);
break;
case R.id.settings_menuitem:
break;
}
drawer.closeDrawer(GravityCompat.END);
return true;
}
});
// Adding menu icon to Toolbar
ActionBar supportActionBar = getSupportActionBar();
if (supportActionBar != null) {
supportActionBar.setHomeAsUpIndicator(R.drawable.ic_notifications);
supportActionBar.setDisplayHomeAsUpEnabled(true);
supportActionBar.setDisplayShowTitleEnabled(false);
}
And the onOptionsItemSelected() that is being called, although not on the correct menu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here.
Log.i("I'm hit options", "I'm hit options"); // also never called...what is going on??
int id = item.getItemId();
switch(id) {
case R.id.emerg_con_menuitem:
break;
case R.id.ride_hist_menuitem:
Log.i("I'm hit options", "I'm hit options");
Intent intent = new Intent(MainActivity.this, loc_report.class);
this.startActivity(intent);
break;
case R.id.settings_menuitem:
break;
case R.id.menu_navigation:
drawer.openDrawer(GravityCompat.END); /*Opens the Right Drawer*/
return true;
}
return super.onOptionsItemSelected(item);
}
Here is the main view activity_mail.xml:
<android.support.v4.widget.DrawerLayout
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"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:background="#drawable/main_background"
style="#style/Theme.AppCompat.DayNight">
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Protectors"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/Protectors"
android:textAlignment="center">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:fitsSystemWindows="true"
app:headerLayout="#layout/navheader"
app:menu="#menu/menu_navigation" />
<android.support.design.widget.NavigationView
android:id="#+id/notifications_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/navheader"
app:menu="#menu/notifications" />
...
The main menu with the clickable icon to open the drawer:
<?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=".MainActivity">
<group android:checkableBehavior="single">
<item // this is the item that's being called on a click
android:id="#+id/menu_navigation"
android:icon="#drawable/ic_menu"
android:title="#string/action_notifications"
android:orderInCategory="100"
app:showAsAction="always" />
</group>
</menu>
and the stuff inside the drawer (the right-hand one):
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/emerg_con_menuitem"
android:title="Emergency Contacts"
/>
<item
android:id="#+id/ride_hist_menuitem"
android:title="Ride History" />
<item
android:id="#+id/settings_menuitem"
android:title="Settings" />
</menu>
Ok, I think I figured this out. I'm still having trouble with the right-drawer links, but I got the left-drawer links to work. It was a layering problem--so I was clicking on the main_menu item (which contains the clickable icon that makes the drawer open) instead of the menu items underneath. To fix this, I added this line of code to fix the order:
NavigationView leftNavigationView = (NavigationView) findViewById(R.id.nav_view);
leftNavigationView.bringToFront(); // <- added this line
And then the OnNavigationItemSelectedListener actually fires as expected.
Related
I'm working on an Android app for an Engineering Design project that includes a drawer. One of my group members elected to use the android.support.design.widget.NavigationView API to do this, and it's been causing us some problems. Our MainActivity class implements onNavigationItemSelectedListener, which I understand acts as a listener for the items in the drawer and other navigation bars. The problem is, when one of these navigation items is selected, the onNavigationItemSelected method that has been implemented is not called (I know this because it's supposed to put out a message through LogCat if it is called). All the references I've found for this API suggest that I've done everything right so far, but I've apparently missed something, so any help is appreciated.
Here is the relevant code from the MainActivity class:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpNavComponents();
setUpMapComponents();
PathfinderDataHandler handler = new PathfinderDataHandler();
}
private void setUpNavComponents()
{
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
navigationView.setNavigationItemSelectedListener(this);
}
private void setUpMapComponents()
{
mapFrag = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
mapFrag.getMapAsync(this);
}
#Override
public boolean onNavigationItemSelected(MenuItem item)
{
// Handle navigation view item clicks here.
int id = item.getItemId();
Log.d(null, "onNavigationItemSelected Called");
if (id == R.id.buildings)
{
// Handle the camera action
Log.d(null, "Buildings selected");
}
else if (id == R.id.blue_phones)
{
Log.d(null, "Blue Phones selected");
}
else if (id == R.id.bus_stops)
{
Log.d(null, "Bus Stops selected");
}
else if (id == R.id.pedways)
{
Log.d(null, "Pedways selected");
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Here is the code from activity_main_drawer.xml (Which holds all the items for the drawer)
<?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:showIn="navigation_view">
<group
android:checkableBehavior="all"
android:enabled="true">
<item
android:id="#+id/buildings"
android:title="#string/building_show_select"
app:actionLayout="#layout/switch_item"
app:showAsAction="always" />
<item
android:id="#+id/blue_phones"
android:title="#string/blue_phone_select"
app:actionLayout="#layout/switch_item"
app:showAsAction="always" />
<item
android:id="#+id/bus_stops"
android:title="#string/bus_stop_select"
app:actionLayout="#layout/switch_item"
app:showAsAction="always" />
<item
android:id="#+id/pedways"
android:title="#string/pedway_select"
app:actionLayout="#layout/switch_item"
app:showAsAction="always" />
</group>
Here is the code for activity_main.xml, which adds the activity_main_drawer to the NavigationView.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" />
<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"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
Another thing to note is that I'm using Switch items instead of regular Menu items.
And before anyone says anything, YES I know this API is depreciated and I should be using NavigationUI in AndroidX, but I don't have time to refactor the app so I have to make do with this.
You have to provide a non null tag for Log.d(String, String), else there will be nothing written to Logcat.
I tried with
Log.d(null, "HelloWorld");
Log.d("TEST", " HelloWorld");
and got only one line in Logcat:
enter image description hereAs you can see I have added 6 item in navigation drawer but on clicking Logout it is not triggered. And sorry for bad code format. I'm new here.
#Override public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_log_out) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.nav_profile:
break;
case R.id.nav_wallet:
break;
case R.id.nav_search:
break;
case R.id.nav_about_us:
break;
case R.id.nav_contact_us:
break;
case R.id.nav_log_out:
Intent intent = new Intent(this,LogIn.class);
FirebaseAuth.getInstance().signOut();
startActivity(intent);
}
This is my XML file for menu item. The id are the same I declared in the XML file. Log out in action bar is working fine but it is not working in Navigation 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">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_profile"
android:icon="#drawable/ic_person_black_24dp"
android:title="Profile" />
<item
android:id="#+id/nav_wallet"
android:icon="#drawable/ic_attach_money_black_24dp"
android:title="EasyFare Wallet" />
<item
android:id="#+id/nav_search"
android:icon="#drawable/ic_directions_bus_black_24dp"
android:title="Search Bus" />
<item
android:id="#+id/nav_about_us"
android:icon="#drawable/ic_folder_shared_black_24dp"
android:title="About Us"/>
<item
android:id="#+id/nav_contact_us"
android:icon="#drawable/ic_email_black_24dp"
android:title="Contact Us" />
<item
android:id="#+id/nav_log_out"
android:icon="#drawable/ic_exit_to_app_black_24dp"
android:title="Log Out" />
</group>
</menu>
activity file with DrawerLayout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<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"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
You have to add brackets for case in logout..
case R.id.nav_log_out:
{
Intent intent = new Intent(this,LogIn.class);
FirebaseAuth.getInstance().signOut();
startActivity(intent);
}
Could you include the code in your activity's onCreate?
One possibility is that you forgot to register your activity as the listener for the navigation view.
mNavigationView.setNavigationItemSelectedListener(this)
Clicking on some other item, let's say the second one, gets this item triggered?
If yes add a break statement in your logout case and also create a default case.
You could also try replacing your code with the following sample.
#SuppressWarnings("StatementWithEmptyBody")
#Override public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.nav_profile:
break;
case R.id.nav_wallet:
break;
case R.id.nav_search:
break;
case R.id.nav_about_us:
break;
case R.id.nav_contact_us:
break;
case R.id.nav_log_out:
{
Intent intent = new Intent(this,LogIn.class);
FirebaseAuth.getInstance().signOut();
startActivity(intent);
break;
}
DrawerLayout drawer;
drawer = findViewById(R.id.THE_ID_OF_YOUR_DRAWER);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
Also make sure that in your OnCreate , OnStart or onResume you include the following
DrawerLayout drawer;
drawer = findViewById(R.id.THE_ID_OF_YOUR_DRAWER);
I will provide you with a code i use for a project of mine and try to see if you find any differences that would explain the fact your code does not work.
AnnouncementsActivity.java
.
.
.
.
public class AnnouncementsActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_announcements);
.
.
.
.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer;
drawer = findViewById(R.id.drawer_layout_astiko);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
toolbar.setNavigationIcon(R.mipmap.ic_toolbar);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
.
.
.
.
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.nav_first_item) {
if(prev_activity_routes){
Intent intent = new Intent(this,RoutesActivity.class);
intent.putExtra("Direction Forth",bus_direction_forth);
intent.putExtra("Team",team);
intent.putExtra("Route name", value1);
intent.putExtra("odigos_onomateponimo",odigos_onomateponimo);
startActivity(intent);
}else{
if(isAstiko){
Intent intent = new Intent(this,TicketIssuanceActivityAstiko.class);
intent.putExtra("Direction Forth",bus_direction_forth);
intent.putExtra("Team",team);
intent.putExtra("Route name", value1);
intent.putExtra("odigos_onomateponimo",odigos_onomateponimo);
startActivity(intent);
}else{
Intent intent = new Intent(this,TicketIssuanceActivity.class);
intent.putExtra("Direction Forth",bus_direction_forth);
intent.putExtra("Team",team);
intent.putExtra("Route name", value1);
intent.putExtra("odigos_onomateponimo",odigos_onomateponimo);
startActivity(intent);
}
}
} else if (id == R.id.nav_second_item) {
Intent intent = new Intent(this,DefinedTicketsActivity.class);
intent.putExtra("Direction Forth",bus_direction_forth);
intent.putExtra("Team",team);
intent.putExtra("Route name", value1);
intent.putExtra("odigos_onomateponimo",odigos_onomateponimo);
intent.putExtra("PreviousActivityRoutes",prev_activity_routes);
intent.putExtra("isAstiko",isAstiko);
startActivity(intent);
}
.
.
.
.
}else if (id == R.id.nav_eighth_item) {
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
}
DrawerLayout drawer;
drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
}
ActivityAnnouncements.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_announcements"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="500dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:theme="#style/NavigationDrawerStyle"
app:headerLayout="#layout/my_nav_header"
app:menu="#menu/my_drawer" />
</android.support.v4.widget.DrawerLayout>
app_bar_announcements.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.e_analysis.AlphaPro.MobileTicketing.AnnouncementsActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/MyTheme">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="65dp"
android:background="?attr/colorPrimary"
app:popupTheme="#style/MyTheme"/>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_announcements" />
</android.support.design.widget.CoordinatorLayout>
content_announcements.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="-0dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:orientation="vertical"
android:background="#color/colorPrimary"
android:gravity="fill"
tools:context="com.e_analysis.AlphaPro.MobileTicketing.AnnouncementsActivity"
tools:showIn="#layout/app_bar_announcements">
.
.
.
.
</LinearLayout>
my_drawer.xml in the menu subfolder
<?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:checkableBehavior="single">
<item
android:id="#+id/nav_first_item"
android:icon="#mipmap/ic_printer_black"
android:title="#string/nav_first_item_value"/>
<item
android:id="#+id/nav_second_item"
android:icon="#mipmap/ic_tune_vertical"
android:title="#string/nav_second_item_value" />
.
.
.
.
<item
android:id="#+id/nav_eighth_item"
android:icon="#mipmap/ic_logout"
android:title="#string/nav_eighth_item_value" />
</group>
</menu>
my_nav_header.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="#dimen/nav_header_height"
android:background="#drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_vertical_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:theme="#style/ThemeOverlay.AppCompat.Dark">
.
.
.
.
</LinearLayout>
This code is working (not as it is ofcourse) so try to do some cross-checking with it and see what you are missing. Most probably it will be something easy to overlook and frustrating when you find out. Good luck!
I have written a piece of code as part of an app where I want to implement a back button on the action bar/tool bar such that when the button is pressed, the previous page (the page/fragment immediately before the current page/fragment) will be displayed.
This is the code for the ToolBar, DrawerLayout, NavigationView and getSupportActionBar():
final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
final NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setVisibility(View.VISIBLE);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setLogo(R.mipmap.ic_launcher);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
I am unable to use ActionBar. For some reason (I don't know why), my Android studio/ program, will not allow me to use the ActionBar. So I am substituting that with the set/getSupportActionBar().
The function used in relation to this are:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_settings, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch (id) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
My activity_main.xml file is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:id="#+id/activity_main"
android:orientation="vertical"
tools:openDrawer="start"
tools:context="com.example.albin.settings_menu.SettingsActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:title="Settings"/>
<android.support.v4.widget.DrawerLayout
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"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar">
</FrameLayout>
<android.support.design.widget.NavigationView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:layout_marginTop="-24dp"
app:menu="#menu/options_menu" />
</android.support.v4.widget.DrawerLayout>
</RelativeLayout>
</LinearLayout>
The problem is that I don't know which is the useful code, which is the useless code and how to mix/join/(add additional codes to) these (codes, methods, variables/objects, fragments, xml layouts) to get the desired outcome, that is, the application of a back button on the action bar/tool bar.
Most of the code above is implemented for the up button, not the back button. I have read at several places that up and back buttons are not the same.
I tried several links on internet as well as on this site, but none of them has just what I need.
Hope someone can give me an clear answer...
You can include the back icon in ToolBar:
Initialize ToolBar:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
You can use an drawable icon as a back button.
toolbar.setNavigationIcon(R.drawable.your_drawable_icon);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// what do you want here
}
});
If you do not want to use drawable icon then:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// what do you want here
}
});
Actually your layout having that issue because you have added toolbar in RelativeLayout so drawer layout is overlapping on it that's why you would not able to click on back arrow, i have fix your layout see below
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:navigationIcon="#drawable/ic_back_black"
app:popupTheme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:title="Settings" />
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/options_menu" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
The simplest way would be to add parent activity in manifest file as developer docs suggest.
<activity
android:name=".ChildActivity"
android:parentActivityName=".ParentActivity" >
and java code you already have done it, setSupportActionbar and setHomeAsUpEnabled.
Edited :
its necessary to add up action for icon to be visible, as mentioned in
Android Developer Docs
So toolbar gives added flexibility to modify title-bar in Android.
As far as why getActionBar is not working and you are compelled to use getSupportActionBar is because you must be using SupportLibrary. SupportLibrary gives backward compatibility to earlier SDK versions.
If you want to modify your title-bar/header/action-bar extensively
then use toolbar otherwise use action-bar.
Add a navigation click listener to your toolbar , like below
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
If you are referencing some actions from the action bar, such as a Save action or a Share one, and you are overriding onOptionsItemSelected method, then you need to define the behavior when the back or home button is clicked:
#Override public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_save:
//save stuff
break;
//this is what you need to add to reference again back/home button
case android.R.id.home:
//do your stuff here, usually back to the home or close the current activity
getActivity().finish();
break;
default:
break;
}
return true;
I want to implement the up button in an android application with only one activity that changes its content with different fragment.
I used the default navigation drawer activity provided by android studio where i added a frameLayout to the content_main.
In the fragment where i want the up botton to be shown i added this line of code in the onCreateView method:
ActionBar actionBar = ((AppCompatActivity)getActivity()).getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
ad this line in the onCreate method:
setHasOptionsMenu(true);
and i added the method to catch the click of it:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
Log.w("second fragment","clicked back");
return true;
}
return super.onOptionsItemSelected(item);
}
in the activiy i set onCreateOptionsMenu like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
but the click of it isn't triggered.
I tried to add a setting button and it is triggered.
I already read a lot of question about this but i can't figure out how to resolve it
setHasOptionsMenu(true) should be called in method onCreate() to let the FragmentManager know that your fragment needs to receive options menu callbacks.
I believe you use this constructor for ActionBarDrawerToggle which takes a Toolbar as a parameter. If you are using this constructor, onOptionsItemSelected will not be called if you click on the indicator. There are questions/answers regarding this problem, for example:
AppCompat v7 Toolbar onOptionsItemSelected not called
But for me, none of them worked perfectly so I used the Toolbar-specific constructor and here it's a workaround for my case. I put a transparent view on top of the toolbar which is "visible" only when I show the back button and I handle the click myself (calling onBackPressed() in my case).
I know it's a kind of hack, but it needed and worked for me.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/main_background">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/layoutMainContent"
android:layout_below="#id/appBar"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
<!-- The important view -->
<View
android:id="#+id/viewFakeBack"
android:layout_width="56dp"
android:layout_height="56dp"
android:clickable="true"
android:visibility="gone"/>
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/navigation_drawer"/>
</android.support.v4.widget.DrawerLayout>
Try by using switch(...) case statement.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
//this will make Hamburger button clickable.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
//this will make the HomeAsUpIndicator button clickable.
switch (item.getItemId()) {
case android.R.id.home:
Log.w("second fragment","clicked back");
break;
}
return super.onOptionsItemSelected(item);
}
Hope this will help you.
i am Using Material Design Navigation View..i created Menu item And linked activity(Activity2.java) with an item(Starred)...and in that activity i extend my Main activity in which there is navigation view so that i can slide the navigation view from that activity too.. but when i slide the navigation view from the second activity the item is not checked and if i press the back button and go to the Main activity the previously checked menu item is shown...how to update the check item in other activity.please help
MainActivity.java
public class MainActivity extends AppCompatActivity {
//Defining Variables
private Toolbar toolbar;
private NavigationView navigationView;
private DrawerLayout drawerLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initializing Toolbar and setting it as the actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initializing NavigationView
navigationView = (NavigationView) findViewById(R.id.navigation_view);
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Checking if the item is in checked state or not, if not make it in 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 being clicked and perform appropriate action
switch (menuItem.getItemId()){
//Replacing the main content with ContentFragment Which is our Inbox View;
case R.id.inbox:
Toast.makeText(getApplicationContext(),"Inbox Selected",Toast.LENGTH_SHORT).show();
ContentFragment fragment = new ContentFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame,fragment);
fragmentTransaction.commit();
return true;
// For rest of the options we just show a toast on click
case R.id.starred:
startActivity(new Intent(MainActivity.this,Activity2.class));
drawerLayout.closeDrawers();
Toast.makeText(getApplicationContext(),"Stared Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.sent_mail:
Toast.makeText(getApplicationContext(),"Send Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.drafts:
Toast.makeText(getApplicationContext(),"Drafts Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.allmail:
Toast.makeText(getApplicationContext(),"All Mail Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.trash:
Toast.makeText(getApplicationContext(),"Trash Selected",Toast.LENGTH_SHORT).show();
return true;
case R.id.spam:
Toast.makeText(getApplicationContext(),"Spam Selected",Toast.LENGTH_SHORT).show();
return true;
default:
Toast.makeText(getApplicationContext(),"Somethings Wrong",Toast.LENGTH_SHORT).show();
return true;
}
}
});
// Initializing Drawer Layout and ActionBarToggle
drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.openDrawer, R.string.closeDrawer){
#Override
public void onDrawerClosed(View drawerView) {
// Code here will be triggered once the drawer closes as we dont 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);
//calling sync state is necessay or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
}
}
Activity2.java
public class Activity2 extends MainActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout frameLayout = (FrameLayout)findViewById(R.id.frame);
// inflate the custom activity layout
LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View activityView = layoutInflater.inflate(R.layout.activity_2, null,false);
// add the custom layout of this activity to frame layout.
frameLayout.addView(activityView);
}
}
activity_main.xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
>
<include
android:id="#+id/toolbar"
layout="#layout/tool_bar"
/>
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
app:headerLayout="#layout/header"
app:menu="#menu/drawer"
/>
</android.support.v4.widget.DrawerLayout>
drawer.xml(menu_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/inbox"
android:checked="false"
android:icon="#drawable/ic_inbox_black"
android:title="#string/inbox_string" />
<item
android:id="#+id/starred"
android:checked="false"
android:icon="#drawable/ic_star_black"
android:title="#string/starred_string" />
<item
android:id="#+id/sent_mail"
android:checked="false"
android:icon="#drawable/ic_send_black"
android:title="#string/sent_mail_string" />
<item
android:id="#+id/drafts"
android:checked="false"
android:icon="#drawable/ic_drafts_black"
android:title="#string/draft_string" />
<item
android:id="#+id/allmail"
android:checked="false"
android:icon="#drawable/ic_email_black"
android:title="#string/all_mail_string" />
<item
android:id="#+id/trash"
android:checked="false"
android:icon="#drawable/ic_delete_black"
android:title="#string/trash_string" />
<item
android:id="#+id/spam"
android:checked="false"
android:icon="#drawable/ic_error_black"
android:title="#string/spam_string" />
</group>
</menu>
Add a protected int variable for storing id of checked menu item
From NavigationView's clickListener add checked menu item id to intent's extras; start yours second Activity with this intent
In second activity get menu item id from extras and set it to class variable from (see 1)
add onPrepareOptionsMenu in yours super-Activity
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
//recreate navigationView's menu, uncheck all items and set new checked item
navigationView.getMenu().clear();
navigationView.inflateMenu(R.menu.drawer);
//setChecked(false) to all yours menu items in NavigationView
navigationView.getMenu().findItem(R.id.SOME_ID_0).setChecked(false);
navigationView.getMenu().findItem(R.id.SOME_ID_1).setChecked(false);
navigationView.getMenu().findItem(R.id.SOME_ID_2).setChecked(false);
...etc
navigationView.setCheckedItem(checkedDrawerItemId);
}
in yours NavigationView's clickListener do not forget to set clicked item's id to Activities class variable and call supportInvalidateOptionsMenu();
Try this in your Activity 2 :
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.starred).setChecked(true);
return true;
}