Navigation Drawer Click stops app and takes back to launch Page - android

I am new to java and android development, have only 3 apps under my belt.
The Problem:
When I click a navigation tab to take me to another activity, it says unfortunately app has stopped and brings me back to the launcher page..
Things I have already looked at fixing:
Grandle Console doesn't reference any errors in the code.
Grandle Console doesn't reference any missing dependancies.
I have ensured all versioning is correct.
I am not using depreciated methods.
The app works if I create my own navigation with buttons, this simple functionality will really streamline the app. It is an app for hiking to log gps with journal entries while mapping a hike using fine-location.
This is the first I have built with the navigation drawer. I have spent days on this problem alone and have finally decided to ask for help, hopefully someone can help out.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
String myurl="file:///android_asset/index.html";
WebView view=(WebView) this.findViewById(R.id.webView);
view.getSettings().setJavaScriptEnabled(true);
view.loadUrl(myurl);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#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;
}
#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.activity_main) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
switch (id){
case R.id.activity_main:
Intent h= new Intent(MainActivity.this,MainActivity.class);
startActivity(h);
break;
case R.id.activity_entry:
Intent e= new Intent(MainActivity.this,EntryActivity.class);
startActivity(e);
break;
case R.id.activity_list:
Intent l= new Intent(MainActivity.this,ListActivity.class);
startActivity(l);
break;
case R.id.activity_bluetooth:
Intent b= new Intent(MainActivity.this,BluetoothActivity.class);
startActivity(b);
break;
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}

First of All, If you put the error log, then that would be very helpful to get quick help. However, as a new developer,
Gradle is a build system, it actually build your project according to
the configuration (managing versions, artifacts, dependencies, etc).
Gradle Console won't show the Errors, you'll find that from Android Monitor/Logcat.
You may mistakenly do some common mistakes
Declaration of activities in the manifest.
looking for an Id of Resources that not belongs to the current layout.
Null Value Exception.

Related

Check whether back button is visible in action bar, or menu button

How to check whether the left button in action bar is menu button or back button? To enable back button we use following:
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
I want to know which button is enable at a particular time. I tried by using stack count but it didn't worked for me.
Menu icon
Back icon
Thanks
You mean this?
set ID:
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add((int groupId, int itemId, int order, charsequence title) .setIcon(drawable ID)
return true;
}
get ID:
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch(item.getItemId())
{
case Menu.First+1 :
break;
case Menu.First+2 :
break;
}
return true;
}
If you are using navigation drawer, then you can do this by knowing state of navigation drawer either open or closed.
Assuming you have defined a drawerlayout in XML:
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
if(mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
//drawer is open
}
if your drawer is open it means you have back icon, else you have bar icon on action bar

How to open Side bar on icon click in Android?

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);
}

Toolbar - Switching from drawer to back button with only one Activity

I've been searching for a while on how to change between the drawer open/close icon (going from a hamburger to the arrow) to a simple back arrow. My application at the moment only has one Activity which switches between several fragments. At one point, I want to transition between one of the main fragments (ie, one of the fragments in the drawer) to a fragment that hierarchically is under the previous fragment (ie, an "Add New " fragment). In this new fragment, I want to have the Toolbar to show the back button instead of the drawer button.
I've been looking around and trying different solutions for quite a while. Here are the most notable:
Change drawer icon back to back arrow - I successfully removed the drawer icon, but in place there's.... nothing. No up caret, no back button, no icon. I suspect this is because my Activity has no parent, but other than a cheap work around (create another Activity that acts as a parent which launches the main Activity), I'm at a lost of what to do.
Switching between Android Navigation Drawer image and Up caret when using fragments - Similar to the above, yet has far more detail. Ultimately, the icon still doesn't turn into a back button.
Android lollipop toolbar switch between open/close drawer and back button - I find this hard to follow, but ultimately the drawer icon can be tapped and does nothing (although I believe I know how to make it act as a back press). However, the icon doesn't change.
At the moment, I'm thinking of a long, arduous method of creating a custom icon that I hide and show (and hide/show the native drawer icon). However, is there a better way to switch between the drawer and back buttons?
As a side yet related question, I've been looking at the Material Design docs, and a few examples have an X in the top left corner. How different is that to implement than implementing the drawer vs back/up buttons?
Thanks~
Edit:
I can figure out how to replace the icon, but how would I get the click event?
So far, this was my best lead:
Cannot catch toolbar home button click event
What I've tried now:
Disabled the DrawerToggle when necessary (ie, mDrawerToggle.setDrawerIndicatorEnabled(useDrawer);)
Added logs in onOptionsItemSelected in my NavigationDrawerFragment, my Activity, as well as the DialogFragment I'm currently testing which run if item.getItemId() == android.R.id.home is true. None of these log statements go off
For better context, I now have a full screen fragment which adds a "Save" button to the menu and changes the drawer icon to an "X". The fragment can get the save menu event, yet not even the Activity and Drawer can get when the X is tapped.
Edit2:
As requested, here is some code. Note that this is all from this Github repo, which I'm actively working on (note that I have a few useless functions here or there from rapid testing).
ActivityMain:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Add the toolbar
mToolbar = (Toolbar) findViewById(R.id.toolbar);
if (mToolbar != null) {
setSupportActionBar(mToolbar);
}
// Initialize the drawer
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
// Set up the drawer
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout),
mToolbar);
// TODO: Check if this helps to catch the main toolbar button click
getSupportActionBar().setDisplayShowHomeEnabled(true);
// Get the titles for the Toolbar
mTitles = getResources().getStringArray(R.array.drawer_items);
mDrawerPosition = -1;
if (savedInstanceState == null) {
// If there was no saved position, then the default, starting position should be used
forceChangeItemSelected(0);
}
else {
// Otherwise, get the saved position from the bundle
int position = savedInstanceState.getInt(KEY_DRAWERPOS);
mNavigationDrawerFragment.setSelectedItem(position);
// Title needs to be re-set
getSupportActionBar().setTitle(mTitles[position]);
}
// If I include the below bit, then the DrawerToggle doesn't function
// I don't know how to switch it back and forth
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(LOG_TAG, "Navigation was clicked");
}
});
}
#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.
Log.d(LOG_TAG, "Activity responding to menu click...");
if(item.getItemId() == android.R.id.home) Log.d(LOG_TAG, "Activity got it....");
// If the fragment is supposed to handle things, then let it
if(mIsFragmentHandlingMenus) return false;
int id = item.getItemId();
if(id == R.id.save) {
// This isn't implemented! If chosen, then there's a bug!
Log.e(LOG_TAG, "onOptionsItemSelected: Save was selected!");
}
return super.onOptionsItemSelected(item);
}
#Override
public void fragmentHandlingMenus(boolean isFragmentHandlingMenus) {
// Simply store the setting
mIsFragmentHandlingMenus = isFragmentHandlingMenus;
// Toggle the drawer as necessary
mNavigationDrawerFragment.toggleDrawerUse(!isFragmentHandlingMenus);
}
NavigationDrawerFragment:
public void toggleDrawerUse(boolean useDrawer) {
// Enable/Disable the icon being used by the drawer
mDrawerToggle.setDrawerIndicatorEnabled(useDrawer);
// TODO: Enable/Disable the drawer even being able to open/close
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d(LOGTAG, "Drawer responding to menu click...");
if(item.getItemId() == android.R.id.home) Log.d(LOGTAG, "Drawer got it....");
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
GoalAdderFragment:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Allow this fragment to handle toolbar menu items
setHasOptionsMenu(true);
// Set up the toolbar
((ActionBarActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
((ActionBarActivity) getActivity()).getSupportActionBar().setHomeAsUpIndicator(android.R.drawable.ic_menu_close_clear_cancel);
((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(getResources().getString(R.string.title_addgoal));
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Cache the Activity as the frag handler if necessary
if(mFragHandler == null)
mFragHandler = (TransactionHandler.FragmentTransactionHandler) getActivity();
// Tell the Activity to let fragments handle the menu events
mFragHandler.fragmentHandlingMenus(true);
}
#Override
public void onDetach() {
super.onDetach();
// Tell the Activity that it can now handle menu events once again
mFragHandler.fragmentHandlingMenus(false);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.save_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d(LOGTAG, "Item id: " + item.getItemId() + " | Save id: " + R.id.save);
Toast.makeText(getActivity(), "Fragment activated!", Toast.LENGTH_SHORT).show();
switch (item.getItemId()) {
case R.id.save:
return true;
case android.R.id.home:
return true;
default:
break;
}
return false;
}
Solution:
This is the ultimate solution I ended up on, with the help of natario's answer below:
NavigationDrawerFragment:
private View.OnClickListener mOriginalListener;
public void setUp(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) {
/* Rest of setting up code */
// Save the default listener after setting everything else up
mOriginalListener = mDrawerToggle.getToolbarNavigationClickListener();
}
// Tells the toolbar+drawer to switch to the up button or switch back to the normal drawer
public void toggleDrawerUse(boolean useDrawer) {
// Enable/Disable the icon being used by the drawer
mDrawerToggle.setDrawerIndicatorEnabled(useDrawer);
// Switch between the listeners as necessary
if(useDrawer)
mDrawerToggle.setToolbarNavigationClickListener(mOriginalListener);
else
mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Custom listener", Toast.LENGTH_SHORT).show();
}
});
}
Put this code into onCreate() of your Activity. Works well for me. Even using compileSdk 23 and higher.
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if(toolbar != null) {
toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
toggle.syncState();
drawer.setDrawerListener(toggle);
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true); // show back button
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
} else {
//show hamburger
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
toggle.syncState();
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
drawer.openDrawer(GravityCompat.START);
}
});
}
}
});
It should work even for latest API 24.
In your activity onCreate() do this:
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
final DrawerLayout drawer = (DrawerLayout) view.findViewById(R.id.drawer_layout);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
final ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
final View.OnClickListener originalToolbarListener = toggle.getToolbarNavigationClickListener();
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
toggle.setDrawerIndicatorEnabled(false);
toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getSupportFragmentManager().popBackStack();
}
});
} else {
toggle.setDrawerIndicatorEnabled(true);
toggle.setToolbarNavigationClickListener(originalToolbarListener);
}
}
});
That's probably not what you would like to hear, but even from a conceptual point of view I would go for a new activity rather than a fragment.
Your main activity is strictly linked to the drawer, so loading a new fragment without any access to the drawer makes no sense to me (but feel free wait for other answers if you think so). A new activity would solve both problems, since it would have no drawer and could be a child of the main one.
Your side question looks spot on also. A "Add New" activity could nicely fit into the "full-screen dialog" visual pattern from the guidelines. See:
http://www.google.com/design/spec/components/dialogs.html#dialogs-full-screen-dialogs
This pattern has a "save", positive button on top-right, and a X. Conceptually, the X button is to cancel/abort a process, rather than navigating up some backstack. It means you are dismissing something without letting any action happen. This fits well for what you want to do.
From a design point of view, it's easily made by a new Activity, that can stay on top of others. Also, if the point of fragments is basically being able to represent two or more at once in tablets and bigger screen - again - I wouldn't be so happy with an old fragment on my left and an "Add New" fragment on the right.
Rather - on tablets - I would go for a floating dialog, as suggested by the guidelines.
http://www.google.com/design/spec/components/dialogs.html#dialogs-confirmation-dialogs
So full-screen activity with a X button for phones, and floating dialog (with buttons at the bottom) for tablets. This, to me, is the most guidelines-coherent approach.
I recommend reading the whole link. On the difference between <- and X,
The X differs from an Up arrow, which is used when the view’s state is constantly being saved or when apps have draft or autosave capabilities. For example, an Up arrow is used in Settings because all changes are committed immediately.
And also
Touching the X in this Settings example will discard all changes. Changes will be saved only upon touching Save.
The answer from #matusalem works great. I just had one bit to add to it - be careful because the drawer can also be opened by swiping in from the left side of the screen. For some, this may be desired, but for me I was disabling the drawer because it didn't make sense in any fragment but my main fragment. The swipe is easily disabled here -
Navigation drawer - disable swipe
This probably belongs in a comment to the answer, but I don't have enough reputation. My apologies.
I had same problem with switching between hamburger menu and back arrow inside same activity when changing fragments. Here is my working solution, hope it helps to someone.
Listener inside your activity:
private View.OnClickListener toolbarMenuListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
//will be called only if toggle.setDrawerIndicatorEnabled(false); !
Log.v(tag,"toggle onClick:"+v.getId()+" android.R.id.home:"+android.R.id.home);
onBackPressed();
}
};
Code onCreate() something like:
...
...
setSupportActionBar(toolbar);
toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
//set listener so you know when back on arrow is pressed
toggle.setToolbarNavigationClickListener(toolbarMenuListener);
...
...
Part you are interested in with comments (Class returned is some of mine class, can set to be void):
/**
* Method to set up action bar drawer.
* #param enableBackDrawerIcon set true if want to show drawer back arrow,
* false to show hamburger menu.
* #param title shown next to drawer icon
*/
public BaseMenusActivity drawerSetupToggle(boolean enableBackDrawerIcon, String title) {
//NOTE: order of methods call is important!
// If you change order order of setDrawerIndicatorEnabled and setDisplayHomeAsUpEnabled
// method calls it won't work, weird bugs will happen (like no icon at all)
if(enableBackDrawerIcon){
Log.v(tag,"show drawer back icon");
//hides hamburger menu and enables View.OnClickListener to be called
toggle.setDrawerIndicatorEnabled(false);
//show back arrow
if(getSupportActionBar()!=null)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else {
Log.v(tag,"show hamburger menu");
//hide back arrow
if(getSupportActionBar()!=null)
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
//shows hamburger menu and prevents View.OnClickListener to be called
toggle.setDrawerIndicatorEnabled(true);
}
setTitle(title);
return this;
}
NOTE: order of called methods is important! Would be better if could just write it in 2 lines like this but WON'T WORK (at least for me):
toggle.setDrawerIndicatorEnabled(!enableBackDrawerIcon);
getSupportActionBar().setDisplayHomeAsUpEnabled(enableBackDrawerIcon);
If you are interested why order of method calls mess things up, look into implementation of those methods.
//This if block makes the menu back button to respond to clicks
//The onOptionsItemSelected fun for whatever reason was not capturing back menu clicks
if (toolbar != null) {
/* toggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
toggle.syncState()
drawer_layout.setDrawerListener(toggle)*/
supportFragmentManager.addOnBackStackChangedListener(object : FragmentManager.OnBackStackChangedListener {
override fun onBackStackChanged() {
if (supportFragmentManager.backStackEntryCount > 0) {
supportActionBar?.setDisplayHomeAsUpEnabled(true) // show back button
toolbar.setNavigationOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
onBackPressed()
}
})
} else {
//show hamburger
supportActionBar?.setDisplayHomeAsUpEnabled(false)
toggle.syncState()
toolbar.setNavigationOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
drawer_layout.openDrawer(GravityCompat.START)
}
})
}
}
})
}
You need to comment out "toggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
toggle.syncState()
drawer_layout.setDrawerListener(toggle)" (4-7 lines) if you are using the auto generated Navigation layout in Android Studio, else the behavior of the back menu button will be erratic. That is what i did and it worked perfectly for me. Hope this helps someone

Android Navigation Drawer Show Up Indicator for Lower Level Fragments

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!

Android: custom icon not displayed in ActionBarDrawerToggle of DrawerLayout

I am trying to implement DrawerLayout. The drawer layout is working fine. But the icon displayed in Top Left corner is android.R.id.home. However I have mentioned my custom icon in ActionBarDrawerToggle as follows:
// Getting reference to the DrawerLayout
drawerLayout = (android.support.v4.widget.DrawerLayout) findViewById(R.id.drawer_layout);
drawerList = (ListView) findViewById(R.id.drawer_list);
// Getting reference to the ActionBarDrawerToggle
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
**R.drawable.icon_top_menu**, R.string.drawer_open,
R.string.drawer_close) {
/** Called when drawer is closed */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
/** Called when a drawer is opened */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
};
// Setting DrawerToggle on DrawerLayout
drawerLayout.setDrawerListener(drawerToggle);
getActionBar().setIcon(R.drawable.icon_top_menu);
// enabling action bar app icon and behaving it as toggle button
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
What's the problem?
You should check your onoptionsItem selected, should missing there...............
as shown below:
#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;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
in place of '.action_settings' try 'icon_top_menu' your icon.......
you should use visibility true/false for the icon menu in each activity where you want to show your icon...and please describe your question properly what you want to do.
To
user1182217
okay i got your problem some what, hope this will help you.
as for icon id you are using "android.R.id.home" which is 'android id' by default,
in place of that use your icon id as R.id.home/ R.id.your_icon_id hope the only error as
per your problem description..........

Categories

Resources