In my app (minSdkVersion
15) I have a Toolbar
instead of ActionBar
and NavigationDrawer
switching between fragments. Some fragments have TabBar
with child fragments inside. These child fragments are ListView
s, and their onItemClickListener
triggers DetailFragment
. I call setDisplayHomeAsUpEnabled()
and an up arrow appears for DetailFragment
but I can't treat it to perform any action, or even show a toast. I've tried this and handling switch (item.getItemId())
in onOptionsItemSelected()
but neither solution works for me. I'm missing something but can't recognize what.
Here's my code:
public class MainActivity extends AppCompatActivity implements FragmentManager.OnBackStackChangedListener {
//...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Listen for changes in the back stack
getSupportFragmentManager().addOnBackStackChangedListener(this);
//Handle when activity is recreated like on orientation Change
shouldDisplayHomeUp();
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
final ActionBar actionBar = getSupportActionBar(); //...
...
public void shouldDisplayHomeUp(){
//Enable Up button only if there are entries in the back stack
boolean canback = getSupportFragmentManager().getBackStackEntryCount()>0;
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(canback);
actionBarDrawerToggle.setDrawerIndicatorEnabled(!canback);
}
}
@Override
public boolean onNavigateUp() {
//This method is called when the up button is pressed. Just the pop back stack.
getSupportFragmentManager().popBackStack();
return true;
}
@Override
public void onBackStackChanged() {
shouldDisplayHomeUp();
}
My entire onOptionsItemSelected
:
@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.
switch (item.getItemId()) {
case android.R.id.home:
Toast.makeText(this, "Up button!", Toast.LENGTH_SHORT).show();
//called when the up affordance/carat in actionbar is pressed
onBackPressed();
break;
case R.id.action_search:
Toast.makeText(this, "Search", Toast.LENGTH_SHORT).show();
break;
}
return super.onOptionsItemSelected(item);
}
I don't know if this other code matters:
// Initializing Drawer Layout and ActionBarToggle
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
actionBarDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,mToolbar,R.string.openDrawer, R.string.closeDrawer){//...
//Setting the actionbarToggle to drawer layout
mDrawerLayout.setDrawerListener(actionBarDrawerToggle);
//calling sync state is necessay or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
In my manifest I have no parent activity.
I found this and it seems to be the right answer but I don't understand how to implement it and have no reputation to ask author.
What can I try to get the up button working?
Two new questions: when I set
public void shouldDisplayHomeUp(){
//Enable Up button only if there are entries in the back stack
if (getSupportActionBar() != null) {
if (getSupportFragmentManager().getBackStackEntryCount()>0) {
actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
}
}
}
...and from the child fragment I press the hardware "back" button I return to the previous fragment and the hamburger icon appears. But the up button still doesn't response from the child fragment. I believe it's because ActionBarDrawerToggle
doesn't manage its behavior anymore. But who manages it instead? If I set this method like this:
public void shouldDisplayHomeUp(){
//Enable Up button only if there are entries in the back stack
if (getSupportActionBar() != null) {
if (getSupportFragmentManager().getBackStackEntryCount()>0) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
}
}
}
...then ActionBarDrawerToggle
handles the click on the up button and opens the drawer like the hamburger icon does. But when I press the hardware back button, the up button (arrow) disappears and the hamburger icon doesn't appear.
So now I see two ways to resolve this problem. First, I could figure out who manages the up button when
actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
and
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
or otherwise, how can I override the ActionBarDrawerToggle
behavior to perform another action when the up button arrow is available instead of the hamburger icon? And how to cause the hamburger icon to appear when I press the hardware back button?