I'm using the new toolbar from the Appcompat V7 library and I'm making an application with navigation drawer and with fragments.
In some fragments I don't want to show the hamburger icon but the arrow instead... That is fine I did this in this way:
mDrawerToggle.setDrawerIndicatorEnabled(false);
mDrawerToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
My question is that: How or where i need to set up the home button lisener or what i need to listen for the "back" button ?
I want to call the main backpressed method and to set back the navigation drawer icon with the hamburger icon..
Add this method in onCreate():
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Then override the onOptionItemSelected() as below:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
You can do it like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
toolbar = (Toolbar)findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
setUpNavigationDrawer();
getFragmentManager().addOnBackStackChangedListener(backStackListener); // listen to the backstack of the fragment manager
}
Define the onBackSTackChangedListener:
private FragmentManager.OnBackStackChangedListener backStackListener = new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
setNavIcon();
};
}
Set the icon according to your fragment's backstack:
protected void setNavIcon() {
int backStackEntryCount = getFragmentManager().getBackStackEntryCount();
drawerToggle.setDrawerIndicatorEnabled(backStackEntryCount == 0);
}
Detect when the drawer icon is pressed:
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle.isDrawerIndicatorEnabled() && drawerToggle.onOptionsItemSelected(item)) {
return true;
}
switch (item.getItemId()) {
case x:
return true;
default:
return false;
}
}
And handle the up button:
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
This works for me. Good luck.
Not sure if this works in OP's case, but in many cases this is probably the simplest option to implement Back button with the AppCompat Toolbar.
Skip all the setHomeButtonEnabled, setDisplayHomeAsUpEnabled and onOptionsItemSelected stuff, and related issues.
Instead, when initialising the Toolbar, simply set 1) navigation icon and 2) navigation OnClickListener for it:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (enableBackNavigation) {
toolbar.setNavigationIcon(R.drawable.ic_back);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
1- Create Toolbar layout;
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/dark_blue"
android:minHeight="?attr/actionBarSize"
local:popupTheme="#style/ThemeOverlay.AppCompat.Light"
local:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
2- Include this in your layout at the place where you want the toolbar to be.
3- Paste the following code in your activity.(extends ActionBarActivity)
private Toolbar mToolbar;
//For Toolbar (Action bar) start
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
mToolbar.setNavigationIcon(R.drawable.ic_back_arrow);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
getSupportActionBar().setTitle("Event Details");
//For Toolbar (Action bar) end
4- change the back click icon to whatever you want.
activate the back button:
getActionBar().setDisplayHomeAsUpEnabled(enable);
and listen for clicks in onBackPressed()
Obviously your activity must extend ActionBarActivity
Simply you can set Navigation icon and make sure you are setting setNavigationOnClickListener() after setting setSupportActionBar(toolbar)
toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
in manifest add these lines under the activity you want the back arrow working
android:parentActivityName="Your parent activity name"
Add setDisplayHomeAsUpEnabled(true)
Toolbar toolbar = findViewById(R.id.toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
Handle the back button
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
Related
I am developing an Android app about music. In this app, I have two fragments: PopFragment e GenresFragment.
In the XML file of PopFragment called fragment_pop.xml, I have toolbar with a back arrow that goes back to GenresFragment.
My toolbar code is this:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
>
<include
android:layout_height="wrap_content"
android:layout_width="match_parent"
layout="#layout/toolbar_layout"
/>
</android.support.design.widget.AppBarLayout>
<ImageButton
android:id="#+id/arrowPop"
android:layout_width="54dp"
android:layout_height="wrap_content"
android:src="#drawable/ic_arrow_back_black_24dp"
style="?android:attr/borderlessButtonStyle"
/>
In the Java file of PopFragment called PopActivity, I have some code but it's not working.
I have this code:
public class PopActivity extends AppCompatActivity implements View.OnClickListener {
public PopActivity() {
// Required empty public constructor
}
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_pop);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolBar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
ImageButton backBtn = (ImageButton)findViewById(R.id.arrowPop);
}
#Override
public void onClick (View view) {
Intent i = new Intent();
switch (view.getId()) {
case R.id.arrowPop:
break;
}
}
Can you help me please?
Thank you
Try something like:
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
inflater.inflate(R.menu.your_menu, menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: {
getActivity().onBackPressed();
break;
}
}
return true;
}
You generally don't need to add your own arrow icon, the Toolbar should be able to handle it for you.
if(shouldShowArrow()) {
drawerLayout.setDrawerLockMode(LOCK_MODE_LOCKED_CLOSED, GravityCompat.START);
drawerToggle.setDrawerIndicatorEnabled(false);
MyActivity.this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else { // hamburglar icon
drawerLayout.setDrawerLockMode(LOCK_MODE_UNLOCKED, GravityCompat.START);
MyActivity.this.getSupportActionBar().setDisplayHomeAsUpEnabled(false);
drawerToggle.setDrawerIndicatorEnabled(true);
}
drawerToggle.syncState();
And then you can define what happens when you click the arrow
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
drawerToggle = new ActionBarDrawerToggle(MyActivity.this, drawerLayout, toolbar, R.string.open, R.string.close) {
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
MyActivity.this.supportInvalidateOptionsMenu();
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
MyActivity.this.supportInvalidateOptionsMenu();
}
};
drawerLayout.setDrawerListener(drawerToggle);
drawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// what to do when you click the arrow
}
});
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setHomeButtonEnabled(true);
}
#Override
protected void onPostCreate(Bundle bundle) {
super.onPostCreate(bundle);
drawerToggle.syncState();
}
#Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
Use the following code as a quick fix, which mimics the back button being pressed.
switch (view.getId()) {
case R.id.arrowPop:
onBackPressed();
break;
}
Using this code, you shouldn't have to define the back button in the toolbar yourself, Android will handle it.
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
Then when you click the back button, Android will call onBackPressed() for you.
This question already has answers here:
When toolbar back button is pressed
(4 answers)
Closed 6 years ago.
how can I create a code for my android app where When I pressed the back button on the toolbar (Action Bar) some code will happening.
I tried but it does not work.
Added in main activity. onbackpress method
#Override
public void onBackPressed() {
super.onBackPressed();
stopActivityTask();
}
You can Try this way..
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// this takes the user 'back', as if they pressed the left-facing
triangle icon on the main android toolbar.
// if this doesn't work as desired, another possibility is to call
stopActivityTask(); // finish() here.
getActivity().onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
If Not Work
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
// Title and subtitle
toolbar.setTitle(R.string.about_toolbar_title);
toolbar.setNavigationIcon(R.drawable.ic_action_back);
toolbar.setNavigationOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
stopActivityTask();
finish();
}
});
private Toolbar toolbar;
Then add this in your onCreate method
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Then you add these lines :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
/*
ADD WHAT YOU WANT TO DO WHEN ARROW IS PRESSED
*/
return super.onOptionsItemSelected(item);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
// click on icon to go back
//triangle icon on the main android toolbar.
if (id == android.R.id.home) {
//your code
return true;
}
return super.onOptionsItemSelected(item);
}
I am using a custom toolbar. I need to add back button to it. Now I am using this code to add the back button.
Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
toolbar.setBackgroundColor(getResources().getColor(R.color.white));
toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.back_arrow));
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
This works fine. I can see the back button added. But consider the case where I am in Fragment1 which has no back button. Now I move to Fragment2 and I add in Back Button. From Fragment 2 I open Fragment 3 and I add the back button again.
Now when I press back button from fragment3 to go back to fragment2 i have to check the Fragment Stack to see whether the back button is required in fragment 2 or not.
Is there any other way to handle back button automatically as we push fragments to stack?
Just add two new line of code. Something like this
Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
toolbar.setBackgroundColor(getResources().getColor(R.color.white));
toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.back_arrow));
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
This assumes you are using an AppCompatActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.tool_bar); // Attaching the layout to the toolbar object
setSupportActionBar(toolbar);
// enabling action bar app icon and behaving it as toggle button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
Then in the onOptionsItemSelected you can override the home button as follows:
#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;
}
else if(id == android.R.id.home){
Intent i= new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
You can handle back icon very easily. If all of your fragment are in single Activity I really recommend to handle this with following way :
first crate a abstract BaseFragment class which implement FragmentManager .OnBackStackChangedListener then put following method inside that :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainActivity = (MainActivity) getActivity();
getFragmentManager().addOnBackStackChangedListener(this);
shouldDisplayHomeUp();
}
#Override
public void onBackStackChanged() {
shouldDisplayHomeUp();
}
public boolean shouldDisplayHomeUp() {
//Enable Up button only if there are entries in the back stack
boolean canBack = false;
try {
canBack = getFragmentManager().getBackStackEntryCount() > 0;
} catch (Exception ex) {
// Log.e(getClass().getCanonicalName(), ex.getMessage());getMessage
}
if (canBack) {
mainActivity.drawerDisable();
} else {
mainActivity.drawerEnable();
}
return canBack;
}
By this way disableDrawer & enableDrawer function handle your Icon and OnBackPressed method handle your BackStack Now in your activity when you press back-icon display if needed. your onBackPressed should be something like this :
int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
if (backStackCount == 0) {
//nothing exist in backStack OS handle it
super.onBackPressed();
} else {
getSupportFragmentManager().popBackStack();
}
See full implementation here.
use Method in Class your Activity
private void setupToolbar(){
Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar=getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
It's works on back pressed function to toolbar
private setUpToolBar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
i have Main activity and Four fragments.
In MainActivity i write this code
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
this is working fine and if you have fragments then create a onBackPressed() method
#Override
public void onBackPressed() {
int position = mViewPager.getCurrentItem();
if(position == 2) { // go back to search / result tab from info detail tab
mViewPager.setCurrentItem(2);
} else if(position == 0) { // switch from result to search tab or go back to home tab
SectionsPagerAdapter sectionsPagerAdapter = (SectionsPagerAdapter) mViewPager.getAdapter();
Fragment fragment = sectionsPagerAdapter.getItem(position);
if(fragment instanceof ResultFragment) {
Bundle bundle = ((ResultFragment) fragment).getArguments();
if(bundle != null) {
sectionsPagerAdapter.replaceFragment(SearchFragment.newInstance(bundle.getString(GlobalInfo.TAG_ID), bundle.getString(GlobalInfo.PART_NO), bundle.getString(GlobalInfo.SERIAL_NO), bundle.getString(GlobalInfo.PART_NAME)), getString(R.string.search), 0);
}
} else {
mViewPager.setCurrentItem(1);
}
}
else if(position == 3){
SectionsPagerAdapter sectionsPagerAdapter = (SectionsPagerAdapter) mViewPager.getAdapter();
Fragment fragment = new ToolMgtFragment();
sectionsPagerAdapter.replaceFragment(fragment,"Tool Mgt", 3);
}
else {
super.onBackPressed();
}
}
I am using the appcompat activity for Android v-21. I want to enable the home button which I have set it to true in my code. I also have overridden the onOptionsItemSelected but it's still not working.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_apply_card);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
//Action bar
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
onBackPressed();
return true;
}
Simple way to add action bar home enable in Appcompat activity
getSupportActionBar().show();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Add this two pulic functions in your activity also--
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
this.finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
}
Following code snippet set navigation icon in toolbar,
toolbar.setNavigationIcon(R.mipmap.ic_launcher);
I hope it will help you.
I know it is an old question but in order to prevent others to devote their time to solve this issue, I want to share the working method for me.
I am not sure about the reason of this. Probably, since ActionBar is deprecated and gave way to Toolbar after AppCompat, some methods of AppCompatActivity may not work as it is expected. Although the Burger (navigation button) is defined as the home button of ActionBar, we could not control click events of this button by using .onOptionsItemSelected(MenuItem). Toolbar view presents us another method to achieve this, toolbar.setNavigationOnClickListener(View.OnClickListener).
To exemplify, I tried to use balysv's MaterialMenuIcon with this method instead of .onOptionsItemSelected(MenuItem) as follows:
private void setupToolbar() {
toolbar = (Toolbar) ((LinearLayout) findViewById(R.id.app_bar)).getChildAt(0);
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (drawerLayout.isDrawerVisible(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
materialMenu.animatePressedState(MaterialMenuDrawable.IconState.BURGER);
} else {
drawerLayout.openDrawer(GravityCompat.START);
materialMenu.animatePressedState(MaterialMenuDrawable.IconState.ARROW);
}
}
});
materialMenu = new MaterialMenuIconToolbar(this, Color.WHITE, MaterialMenuDrawable.Stroke.THIN) {
#Override public int getToolbarViewId() {
return R.id.toolbar;
}
};
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerLayout.setDrawerListener(new DrawerLayout.SimpleDrawerListener() {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
materialMenu.setTransformationOffset(
MaterialMenuDrawable.AnimationState.BURGER_ARROW,
isDrawerOpened ? 2 - slideOffset : slideOffset
);
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
isDrawerOpened = true;
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
isDrawerOpened = false;
}
#Override
public void onDrawerStateChanged(int newState) {
super.onDrawerStateChanged(newState);
if (newState == DrawerLayout.STATE_IDLE) {
if (isDrawerOpened) materialMenu.setState(MaterialMenuDrawable.IconState.ARROW);
else materialMenu.setState(MaterialMenuDrawable.IconState.BURGER);
}
}
});
}
I hope it helps.
I am using Xamarin Android, and for AppCompatActivity I also used this method which did not work for me.
SupportActionBar.SetHomeButtonEnabled(true);
but after finding on internet and I found another method, which worked for me, and showed the home navigation button.
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
All of my fragments are controlled through ActionBarActivity (mainActivity), inside mainActivity a DrawerLayout is implemented and all the child fragments are pushed through drawerLayout's list item click. The problem that I'm facing is after pushing a fragment through drawerLayout I want to change the drawer icon into back icon of ToolBar so that user can navigate to previous fragment and to handle the callback of android.R.id.home either inside the same fragment or inside the mainActivity.
The code that I am using is:
MainActivity.java
public class MainActivity extends ActionBarActivity {
private DrawerLayout layoutDrawer;
private ActionBarDrawerToggle drawerToggler;
private Stack<Fragment> stack;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
stack = new Stack<Fragment>();
layoutDrawer = (DrawerLayout) findViewById(R.id.layout_drawer);
drawerToggler = new ActionBarDrawerToggle(this, layoutDrawer, toolbar,
R.string.app_name, R.string.app_name);
layoutDrawer.setDrawerListener(drawerToggler);
setUpDrawerList();
pushFragment(new FirstFragment(), true);
Session.setContext(getApplicationContext());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggler.isDrawerIndicatorEnabled()
&& drawerToggler.onOptionsItemSelected(item))
return true;
switch (item.getItemId()) {
case android.R.id.home:
Toast.makeText(this, "Back from activity", Toast.LENGTH_SHORT)
.show();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggler.syncState();
}
#Override
public void onBackPressed() {
popFragment();
}
private void setUpDrawerList() {
ListView listView = (ListView) findViewById(R.id.list_drawer);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
Arrays.asList(new String[] { "First Fragment",
"Second Fragment" }));
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
layoutDrawer.closeDrawers();
drawerToggler.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
pushFragment(getFragment(position), true);
}
});
}
private Fragment getFragment(int pos) {
switch (pos) {
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
}
return null;
}
public void pushFragment(Fragment fragment, boolean add) {
FragmentTransaction transation = getSupportFragmentManager()
.beginTransaction();
if (add)
stack.push(fragment);
transation.replace(R.id.layout_content, fragment);
transation.commit();
}
public void popFragment() {
if (!stack.isEmpty()) {
Fragment fragment = stack.elementAt(stack.size() - 2);
stack.pop();
pushFragment(fragment, false);
} else
super.onBackPressed();
drawerToggler.setDrawerIndicatorEnabled(stack.size() == 1);
}
public void clearBackStack() {
stack.clear();
}
}
FirstFragment.java
public class FirstFragment extends Fragment {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_first, container, false);
}
#Override
public void onResume() {
super.onResume();
ActionBar actionBar = ((ActionBarActivity)getActivity()).getSupportActionBar();
actionBar.setTitle("First Fragment");
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.fragment_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
Toast.makeText(getActivity(), "Back from fragment", Toast.LENGTH_SHORT).show();
getActivity().onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
}
From the above code I am not able to get the callback of android.R.id.home and setting home button is not working everytime actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true);
Any help will be really appreciated.
Thanks
Add a toolbar to your xml
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment title"/>
</android.support.v7.widget.Toolbar>
Then inside your onCreateView method in the Fragment:
Toolbar toolbar = view.findViewById(R.id.toolbar);
toolbar.setNavigationIcon(R.drawable.ic_back_button);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().onBackPressed();
}
});
You have to manage your back button pressed action on your main Activity because your main Activity is container for your fragment.
First, add your all fragment to transaction.addToBackStack(null) and now navigation back button call will be going on main activity. I hope following code will help you...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
you can also use
Fragment fragment =fragmentManager.findFragmentByTag(Constant.TAG);
if(fragment!=null) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment).commit();
}
And to change the title according to fragment name from fragment you can use the following code:
activity.getSupportActionBar().setTitle("Keyword Report Detail");
I have head around lots of solutions and none of them works perfectly. I've used variation of solutions available in my project which is here as below. Please use this code inside class where you are initialising toolbar and drawer layout.
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);// show back button
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
} else {
//show hamburger
drawerFragment.mDrawerToggle.setDrawerIndicatorEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
drawerFragment.mDrawerToggle.syncState();
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
drawerFragment.mDrawerLayout.openDrawer(GravityCompat.START);
}
});
}
}
});
Probably the cleanest solution:
abstract class NavigationChildFragment : Fragment() {
abstract fun onCreateChildView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View?
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val activity = activity as? MainActivity
activity?.supportActionBar?.setDisplayHomeAsUpEnabled(true)
setHasOptionsMenu(true)
return onCreateChildView(inflater, container, savedInstanceState)
}
override fun onDestroyView() {
val activity = activity as? MainActivity
activity?.supportActionBar?.setDisplayHomeAsUpEnabled(false)
setHasOptionsMenu(false)
super.onDestroyView()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val activity = activity as? MainActivity
return when (item.itemId) {
android.R.id.home -> {
activity?.onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
}
}
Just use this class as parent for all Fragments that should support navigation.
You can use Toolbar inside the fragment and it is easy to handle. First add Toolbar to layout of the fragment
<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_height="wrap_content"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:minHeight="?attr/actionBarSize"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="?attr/colorPrimaryDark">
</android.support.v7.widget.Toolbar>
Inside the onCreateView Method in the fragment you can handle the toolbar like this.
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setTitle("Title");
toolbar.setNavigationIcon(R.drawable.ic_arrow_back);
IT will set the toolbar,title and the back arrow navigation to toolbar.You can set any icon to setNavigationIcon method.
If you need to trigger any event when click toolbar navigation icon you can use this.
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//handle any click event
});
If your activity have navigation drawer you may need to open that when click the navigation back button. you can open that drawer like this.
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
drawer.openDrawer(Gravity.START);
}
});
Full code is here
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//inflate the layout to the fragement
view = inflater.inflate(R.layout.layout_user,container,false);
//initialize the toolbar
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setTitle("Title");
toolbar.setNavigationIcon(R.drawable.ic_arrow_back);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//open navigation drawer when click navigation back button
DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
drawer.openDrawer(Gravity.START);
}
});
return view;
}
First you add the Navigation back button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
Then, add the Method in your HostActivity.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()==android.R.id.home)
{
super.onBackPressed();
Toast.makeText(this, "OnBAckPressed Works", Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
Try this, definitely work.
if you are using androidx fragment and want to go back to MainActivity when back home button is clicked, use the following codes .
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
....
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
requireActivity().onBackPressed();
}
return super.onOptionsItemSelected(item);
}
(Kotlin)
In the activity hosting the fragment(s):
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
onBackPressed()
return true
}
}
return super.onOptionsItemSelected(item)
}
I have found that when I add fragments to a project, they show the action bar home button by default, to remove/disable it put this in onViewCreated() (use true to enable it if it is not showing):
val actionBar = this.requireActivity().actionBar
actionBar?.setDisplayHomeAsUpEnabled(false)
The easiest solution I found was to simply put that in your fragment :
androidx.appcompat.widget.Toolbar toolbar = getActivity().findViewById(R.id.toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
NavController navController = Navigation.findNavController(getActivity(),
R.id.nav_host_fragment);
navController.navigate(R.id.action_position_to_destination);
}
});
Personnaly I wanted to go to another page but of course you can replace the 2 lines in the onClick method by the action you want to perform.
Generic method in Kotlin which can handle both the title bar back press action as well as navigation bar back press action and can be called from all the fragments is :
fun configureToolbarBackPress(
customToolBar: Toolbar,
parentVw: View,
activity: Activity,
title: String,
targetResId: Int
) {
customToolBar.setNavigationIcon(R.drawable.ic_arrow_back)
customToolBar.title = title
customToolBar.setNavigationOnClickListener {
parentVw.findNavController().navigate(targetResId)
}
(activity as DashboardActivityNew).onBackPressedDispatcher.addCallback(
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
parentVw.findNavController().navigate(targetResId)
}
}
)
}
Now call this method onViewCreated() from any of the fragment as follows :
AppUtils.configureToolbarBackPress(
customToolbar as Toolbar,
view,
requireActivity(),
getString(R.string.title),
R.id.mainFragment
)
Include the toolbar in fragment.xml as follows :
<include
android:id="#+id/customToolbar"
layout="#layout/dashboard_toolbar" />
The layout of dashboard_toolbar.xml is as follows :
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar 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/abc_action_bar_default_height_material"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="#color/colorPrimary"/>
OnToolBar there is a navigation icon at left side
Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
toolbar.setTitle(getResources().getString(R.string.title_activity_select_event));
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
By using this at left side navigation icon appear and on navigation icon click it call parent activity.
and in manifest we can notify system about parent activity.
<activity
android:name=".CategoryCloudSelectActivity"
android:parentActivityName=".EventSelectionActivity"
android:screenOrientation="portrait" />