This is the beahviour of my App (only 1 is right, of course):
Of course I want only one item at the moment checked.
I divided the items in two groups (to add the divider, see my previous question: How add horizontal separator in navdrawer? )
This is the nav_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/group1" >
<item
android:id="#+id/home"
android:checked="false"
android:icon="#drawable/ic_home_black_24dp"
android:title="#string/list_home" />
<item
android:id="#+id/list_event"
android:checked="false"
android:icon="#drawable/ic_list_black_24dp"
android:title="#string/list_event" />
</group>
<group
android:checkableBehavior="single"
android:id="#+id/group2" >
<item
android:id="#+id/settings"
android:checked="false"
android:icon="#drawable/ic_settings_black_24dp"
android:title="#string/settings" />
</group>
</menu>
This is the BaseApp that manage the NavDrawer:
package com.xx.views;
import android.support.design.widget.NavigationView;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.support.v7.app.ActionBarDrawerToggle;
import android.os.Bundle;
import android.view.View;
import com.xx.R;
import com.xx.mappers.DateManager;
public class BaseApp extends AppCompatActivity {
//Defining Variables
protected String LOGTAG = "LOGDEBUG";
protected Toolbar toolbar;
protected NavigationView navigationView;
protected DrawerLayout drawerLayout;
private DateManager db = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.base_layout);
navigationView = (NavigationView) findViewById(R.id.navigation_view);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, new DashboardFragment());
fragmentTransaction.commit();
setNavDrawer();
// make home as checked
navigationView.getMenu().getItem(0).setChecked(true);
}
private void setNavDrawer(){
// Initializing Toolbar and setting it as the actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initializing NavigationView
//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()) {
case R.id.home:
DashboardFragment dashboardFragment = new DashboardFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, dashboardFragment,"DASHBOARD_FRAGMENT");
fragmentTransaction.commit();
return true;
case R.id.list_event:
ListEventFragment fragmentListEvent = new ListEventFragment();
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, fragmentListEvent);
fragmentTransaction.commit();
return true;
case R.id.settings:
SettingsFragment fragmentSettings = new SettingsFragment();
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, fragmentSettings);
fragmentTransaction.commit();
return true;
default:
return true;
}
}
});
// Initializing Drawer Layout and ActionBarToggle
drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
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 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();
}
private void eraseTable(){
db=new DateManager(this);
db.resetTable();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.menu_main, 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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Thank you very much
This could help you: Try to removing the tag android:checkableBehavior="single" from xml and set android:checkable = “true” for each item individually, then declare a MenuItem object in the activity and in onNavigationItemSelected event if previously declared MenuItem object is not null then set checked value as false for it and then save current selected menuItem received as parameter to earlier declared MenuItem object.
This will set checked selection on even subitems.
if (prevMenuItem != null) {
prevMenuItem.setChecked(false);
}
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
prevMenuItem = menuItem;
return true;
I found this solutions here
If you are using groups and android:checkableBehavior="single", then all you need to do is set the single item as the checked item in the navigation view (not simply the item as checked with item.setChecked(true)):
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
//item.setChecked(true); //Won't work, will leave previous item checked too.
navigationView.setCheckedItem(id); //this will check single item
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Now, whether you select or emulate select for an item, it will check only one item at a time.
Put both group inside single group an set
android:checkableBehavior="single"
Create a parent group
You would have to implement a custom adapter, custom/model, custom function to uncheck other items on click.
I suggest you to use this library. Its a material navigation drawer implementation, it already has all this logic implemented. If you dont want to go with a lib, them you should check how its done on this library code and adapt to your needs.
Related
I have only one user setting in my app, and I want to put it into the navigation drawer with a switch added to the given menu item.
Here is the relevant menu code:
<item
android:id="#+id/nav_dark"
android:checkable="true"
android:icon="#drawable/round_brightness_4_24"
android:title="#string/menu_dark"
app:actionViewClass="android.widget.Switch" />
The switch does appear on the right side of the menu item.
My listener:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == R.id.nav_dark) {
// code to apply dark or light theme
// works as expected
}
else {
// code to handle regular menu items
// it works too
}
return true;
}
My problems:
When I tap on R.id.nav_dark the item gets selected. I would like the colored overlay to stay on (or jump back to) the previous menu item, whose fragment is actually shown behind the drawer.
The switch does not react accordingly, even if I use item.setChecked(true) manually. I would like the switch to be turned on when the dark theme is enabled and turned off when it's disabled.
Tapping on the switch itself does not pass the event to the menu item. I would like them to work in sync.
I have seen checkboxes and swiches working like this in other applications, although, most of them were in the app bar's overflow menu. (I have tried mine with a checkbox too, but no difference.)
I solved this problem using this thread: Switch in Navigation drawer item with Design Support Library on Android
In this example the dedicated menu item switches between a light and dark theme, but you can use it to toggle any settings, of course.
Problems to solve
Implement our own onNavigationItemSelected listener, because the default solution created by Android Studio prevents the use of a dedicated menu item.
Implement the fragment transaction and toolbar handling logic.
Implement the onCheckedChange listener of the switch.
What we do is capture clicks on the menu items. If it's a regular item, we change the fragment behind the drawer. If it's the dedicated item with the switch, we manually toggle the switch, which calls its listener.
The actual code (changing the theme in this case) is handled by the listener of the switch. If you click on the switch itself, the listener will be called directly.
Relevant code from activity_main_drawer.xml menu file
<item
android:id="#+id/nav_dark"
android:checkable="true"
android:icon="#drawable/round_brightness_4_24"
android:title="#string/menu_dark"
app:actionViewClass="android.widget.Switch" /> <!-- you can also use a CheckBox -->
Relevant code from MainActivity.java
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, Switch.OnCheckedChangeListener {
private Toolbar toolbar;
private DrawerLayout drawerLayout;
private ActionBarDrawerToggle toggle;
private NavigationView navigationView;
private Switch switchDark;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(getResources().getString(R.string.toolbar_title));
setSupportActionBar(toolbar);
// We have to handle the fragment changes manually,
// because what we do conflicts with the default solution created by Android Studio
drawerLayout = findViewById(R.id.drawer_layout);
toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.setDrawerIndicatorEnabled(true);
toggle.syncState();
navigationView = findViewById(R.id.nav_view);
// Check the menu item connected to the default fragment manually
navigationView.getMenu().findItem(R.id.nav_item1).setChecked(true);
navigationView.setNavigationItemSelectedListener(this); // See below!
switchDark = (Switch)navigationView.getMenu().findItem(R.id.nav_dark).getActionView();
// Set the default state of the switch connected to the menu item
switchDark.setChecked(AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES);
switchDark.setOnCheckedChangeListener(this); // See below!
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
// Handle the menu item with the switch
if (item.getItemId() == R.id.nav_dark) {
((Switch)item.getActionView()).toggle(); // Call the onCheckedChangeListener of the switch and let it do the work
return false; // Prevent the menu item to get selected (No overlay indicator will appear)
}
// Handle the other menu items
// We have to do this, because we deleted the default solution created by Android Studio
Fragment newFragment = null;
if (item.getItemId() == R.id.nav_item1) {
newFragment = new CustomFragment();
toolbar.setTitle(getResources().getString(R.string.custom_fragment_title));
}
else if (item.getItemId() == R.id.nav_item2) {
newFragment = new OtherFragment();
toolbar.setTitle(getResources().getString(R.string.other_fragment_title));
}
// Start the fragment transition manually
if (newFragment != null) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.nav_host_fragment, newFragment);
transaction.addToBackStack(null);
transaction.commit();
drawerLayout.close();
}
return true; // The selected item will have the overlay indicator
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(buttonView.getContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
int themeID;
if (isChecked) {
themeID = AppCompatDelegate.MODE_NIGHT_YES;
}
else {
themeID = AppCompatDelegate.MODE_NIGHT_NO;
}
AppCompatDelegate.setDefaultNightMode(themeID); // Change the theme at runtime
editor.putInt("themeID", themeID); // Save it to be remembered at next launch
editor.apply();
}
}
try this one.
<item
app:actionViewClass="androidx.appcompat.widget.SwitchCompat"
android:icon="#drawable/message"
android:title="All inboxes"
android:id="#+id/inbox"
/>
this above is the menu item we need
in order to get click events follow below steps mentioned
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
if (item.getItemId()==R.id.inbox){
((SwitchCompat) item.getActionView()).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked){
Toast.makeText(buttonView.getContext(), "Checked", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(buttonView.getContext(), "unChecked", Toast.LENGTH_SHORT).show();
}
}
});
}
Toast.makeText(MainActivity.this, ""+item.getTitle(), Toast.LENGTH_SHORT).show();
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
});
we already given our action class in menu item from xml .
we just need to verify which item it was and when it happens we can get the actionviewclass that we had assigned
and an onclicklistener on it .. this one worked for me .
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 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 implemented Hamburger bar with App toolbar and both of them are working fine. Following is the snapshot of toolbar and hamburgerbar:
Hamburger bar
I can open this bar by sliding it but I also want to make it open by clicking on drawable icon (right top corner icon). How can i do that?
MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
drawerFragment = (FragmentDrawer)
getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), toolbar);
drawerFragment.setDrawerListener(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.menu_main, 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();
return super.onOptionsItemSelected(item);
}
I don't think so that I need to do some changes in layout files. What do I have to add in MainActivity file to make it possible?
I am newbie in Android code. Any help will be appreciable.
Using the Toolbar component should be fairly easy to achieve this by using a similar code to this:
Toolbar toolbar = (Toolbar) findViewById(R.id.home_toolbar);
toolbar.inflateMenu(R.menu.menu_home);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.action_settings) {
mDrawerLayout.openDrawer(Gravity.RIGHT); // where mDrawerLayout is your android.support.v4.widget.DrawerLayout in your activity's xml layout.
}
return false;
}
});
EDIT:
The key component here is the menu_home.xml file which goes to your res/menu folder. You can add your desired menu item there, customize it's icon and even more, add as many items as you'd like to have on the right side of the toolbar(Obviously handle the openDrawer() method on whichever menu item you need - the recommended one is the rightmost though).
Use the openDrawer() method.
private DrawerLayout mDrawerLayout;
...
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
...
mDrawerLayout.openDrawer(Gravity.END); // or whatever gravity the of the drawer you want to open
Use Activity's onOptionsItemSelected(MenuItem menuItem) method:
First of all, keep the reference to your DrawerLayout in a class field:
DrawerLayout drawerLayout;
Somewhere in onCreate put this:
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout)
And implement the method:
#Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
// if you want the default back/home hamburger menu item just put android.R.id.home instead
if (menuItem.getItemId() == R.drawable.icon_navigation) {
drawerLayout.openDrawer(GravityCompat.END);
}
return super.onOptionsItemSelected(menuItem);
}
I have some issues switching navigation drawer functionality to up functionality at lower level fragment. I have read this thread to manage to show the up indicator. But when pressing the button, it'll open up the navigation drawer instead of going back to previous fragment. And I can't set action bar title in EditUserFragment to "Edit Profile".
I'm using the navigation drawer template available in Android Studio.
I have three levels:
MainActivity with navigation drawer that consists of Home and Profile items
UserFragment titled with "Profile" that has an option item that'll bring up EditUserFragment
EditUserFragment (lower level fragment) is triggered by UserFragment
MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
R.drawable.ic_launcher, R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
}
#Override
public void onBackPressed() {
super.onBackPressed();
// this won't change the drawer indicator back
drawerToggle.setDrawerIndicatorEnabled(true);
// this works
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
public void onSectionAttached(int number) {
// Show the corresponding title on the action bar when clicked and open corresponding
// fragments.
Fragment fragment = null;
switch (number) {
case 1:
mTitle = getString(R.string.title_home);
break;
case 2:
mTitle = getString(R.string.title_profile);
fragment = new UserFragment();
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
public void restoreActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setTitle(mTitle);
}
public void setActionBarTitle(String title){
getActionBar().setTitle(title);
Log.d("Title 2", getActionBar().getTitle().toString());
}
onBackPressed is working partially (commented in code) when I pressed back button on phone (not up button on action bar).
UserFragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_profile, container, false);
drawerLayout = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
drawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout,
R.drawable.ic_launcher, R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
return view;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_edit:
drawerToggle.setDrawerIndicatorEnabled(false);
// Disable sliding from edge to open drawer
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
getFragmentManager().beginTransaction()
.replace(R.id.container, new EditUserFragment())
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.addToBackStack(null)
.commit();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
EditUserFragment
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
((MainActivity) getActivity()).setActionBarTitle("Edit Profile");
Log.d("Title", getActivity().getActionBar().getTitle().toString());
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Get item selected and deal with it
Log.d("KEY: ", String.valueOf(item.getItemId()));
switch (item.getItemId()) {
case android.R.id.home:
Log.d("EditUserFragment", "I'm here");
getActivity().onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true); works as expected that up caret is showing instead of drawer; though when tapping it, it's opening up drawer instead of going back to previous fragment. In addition, the code under case android.R.id.home is never executed.
And I try to set action bar title to "Edit Profile" from "Profile". The log shows me "Edit Profile", but the actual running app shows me "Profile" for some reason.
What I want to achieve is be able to go back to UserFragment from EditUserFragment by tapping the up indicator (right now the up indicator is opening up navigation drawer). And show correct title in EditUserFragment.
Any help is greatly appreciated!!
After days of analyzing, I discovered that the problem is I am using the built-in navigation drawer activity when creating it. The built-in separate the tasks into two. MainActivity and NavigationDrawerFragment. Thus, the drawerToggle I have in MainActivity is not the same as the real one in NavigationDrawerFragment.
Oroginally, MainActivty calls NavigationDrawerFragment to setup all the things needed for navigation drawer. I SOLVED this by implementing navigation drawer in my MainActivity, so I'll have only one drawerToggle. Though, I still can't find the way to make it work if I have everything (the navigation drawer variables) in NavigationDrawerFragment rather than MainActivity. If anyone knows the answer to that, feel free to leave a comment!