with the help of these Android Docs.I am trying to do a action bar Back button.I get an Action Bar Back Button like these below image:
Output:
But My problem is After watching the Gallery images I press the action bar back button.
Then it is not working.But it have to go back to previous page.
Listed below are the codings.
GalleryActivity.java:
import android.app.ActionBar;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.view.MenuItem;
import com.fth.android.R;
public class GalleryActivity extends FragmentActivity {
private int position;
private static String id;
private static String name;
private DemoCollectionPagerAdapter mDemoCollectionPagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
position = getIntent().getExtras().getInt("position");
id = getIntent().getExtras().getString("id");
name = getIntent().getExtras().getString("name");
mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getSupportFragmentManager());
// Set up action bar.
final ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
// getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME|ActionBar.DISPLAY_USE_LOGO|ActionBar.DISPLAY_HOME_AS_UP);
// Set up the ViewPager, attaching the adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mDemoCollectionPagerAdapter);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent upIntent = new Intent(this, HomeActivity.class);
upIntent.putExtra("position", position);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
TaskStackBuilder.from(this)
.addNextIntent(upIntent)
.startActivities();
finish();
} else {
NavUtils.navigateUpTo(this, upIntent);
}
return true;
}
return super.onOptionsItemSelected(item);
}
}
GalleryDetailFragment.java:
import com.sit.fth.model.GalleryDetail;
import com.sit.fth.util.APIServiceHandler;
import com.sit.fth.util.AppConstants;
import com.sit.fth.util.AppPromoPager;
public class GalleryDetailFragment extends BaseFragment implements
PromoPagerListener {
private TextView countView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
this.setHasOptionsMenu(true);
id = getArguments().getString("id");
name = getArguments().getString("name");
View view = inflater.inflate(R.layout.app_pager, null);
return view;
}
}
Anybody can help me if you know how to solve these.Thank You.
I solved these problem by adding the below coding in GalleryActivity.
ActionBar actionBar;
actionBar=getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
In MainActivity:
Previously,
public class HomeActivity extends BaseActivity
Then I change into
public class HomeActivity extends FragmentActivity
In GalleryFragment:
I use Intent to pass it to the GalleryActivity.
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Gallery gallery = (Gallery) arg0.getAdapter().getItem(arg2);
Intent intent = new Intent(getActivity(), GalleryActivity.class);
intent.putExtra("position", position);
intent.putExtra("id", gallery.getGalId());
intent.putExtra("name", gallery.getAlbumTitle());
startActivity(intent);
// mCallback.OnGalItemSelected(gallery.getGalId(),gallery.getAlbumTitle());
}
Please read this
you should have something like this:
<activity
android:name="com.sit.fth.activity.HomeActivity"
android:screenOrientation="portrait">
</activity>
<activity
android:name="com.sit.fth.activity.GalleryActivity"
android:screenOrientation="portrait"
android:parentActivityName="com.sit.fth.activity.HomeActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.sit.fth.activity.HomeActivity"/>
</activity>
then calling NavUtils.navigateUpFromSameTask(this) will cause navigating to parent activity (HomeActivity).
You need to call setDisplayHomeAsUpEnabled(true) method in the onCreate method and override onSupportNavigateUp() and call onBackPressed() in it as below. That's it. done :)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_help);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
You have just to add the following line to the activity in the manifest.xml. The parent activity is the activity to which you want to go back.
android:parentActivityName=".activities.MainActivity"
Try like
First of all you need to use addToBackStack() before commit() for Fragments
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
if(getSupportFragmentManager().getBackStackEntryCount()>0)
getSupportFragmentManager().popBackStack();
return true;
}
return super.onOptionsItemSelected(item);
}
Best and easy answer is add the parent activity name in Manifest file, so Actionbar back button will work.
For that under that Activity tag of Manifest File use
android:parentActivityName=".MyCustomParentActivity"
if the home button is shown. you should add an action to the home button through onOptionItemSelected fun (arrow in your case) by default there's no action. so it's totally normal that it's not working. Please add this fun to your activity :
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when {
item.itemId == android.R.id.home -> {
finish()
true
}
else -> super.onOptionsItemSelected(item)
}
}
None of the answers provided here worked for me. I had to put the switch inside the onMenuItemSelected method. I'm aware this is not what is stated in the Android documentation, but still, it worked, so I just thought I'd leave this here for people who run into the same issue. My problem involved an Activity instead of a Fragment though, but that should be pretty much the same.
class FooActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
getActionBar().setHomeButtonEnabled(true);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return false;
}
}
To me, I had to set mDrawerToggle.setToolbarNavigationClickListener(...) to a listener that triggers the back action. Otherwise it does nothing. This is what the source code of ActionBarDrawerToggle looks like:
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mDrawerIndicatorEnabled) {
toggle();
} else if (mToolbarNavigationClickListener != null) {
mToolbarNavigationClickListener.onClick(v);
}
}
});
So the default behaviour is actually to call our listener, and not do any magic on its own.
Use on SupportNavigateUp() method and call onBackPressed in this method.
onCreate
{
...
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
resetActionBar();
...
}
public void resetActionBar()
{
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
#Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
int count = fm.getBackStackEntryCount();
if(count == 0) {
// Do you want to close app?
showDialog();
}else{
super.onBackPressed();
}
}
#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();
Log.i("coming", "comming");
//noinspection SimplifiableIfStatement
if(id==android.R.id.home){
if (getSupportFragmentManager().getBackStackEntryCount() > 0)
onBackPressed();
else
drawerLayout.openDrawer(navigationView);
return true;
}
return super.onOptionsItemSelected(item);
}
Here is one more thing to check for in case the other answers here (or here or here or here) don't work.
I had copied some code from another activity that disabled the menu. Deleting this method (and applying the solutions given in the others answers) allowed the up button to work.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// hide the menu
return false;
}
In my case I had overridden the onCreateOptionsMenu method and I forgot to call super at the end.
Tool bar enable back button for Kotlin binding
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_times_ic)
Related
I created a setting activity. When the user clicks setting it move from mainactivity to settingsactivity but it does not go to the previous page when I click the back button at the top of the action bar it says app keeps stopping. If I click phone back button it works.
Here I attached my coding correct it. How can I do this?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_activity);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings, new SettingsFragment())
.commit();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
NavUtils.navigateUpFromSameTask(this);
}
return super.onOptionsItemSelected(item);
}
public static class SettingsFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey)
{
setPreferencesFromResource(R.xml.root_preferences, rootKey);
}
}
It's preferred to use finish() in an activity, since it'll automatically go back to the last activity.
first, add to the tollbar in the XML file
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" >
<ImageView
android:id="#+id/home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_back"/>
</androidx.appcompat.widget.Toolbar>
and
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
I need set back icon in my toolbar. I created my toolbar using android.support.v7.widget.Toolbar and for back using this code first set onClick to my back icon by this code:
ImageView backIcon = findViewById(R.id.back_icon);
backIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent=new Intent(CreateNewItem.this,MainActivity.class);
startActivity(intent);
finish();
}
});
and add this code:
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
it's work and back to activity but my problem it's when using back icon and back to activity see recyclerView is empty and activity not have data. what is my problem?
If You are using Toolbar then no need to set custom back icon, you have to just override this method
#Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case android.R.id.home:
onBackPressed();
}
return (super.onOptionsItemSelected(menuItem));
}
and enable Toolbar:
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Happy coding!!
I want to Prevent Page reload or Freeze the Current Web-view When I Select any menu from option menu
This is My Webview
public class MyWebV extends AppCompatActivity {
private WebView webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mwview);
Toolbar toolbar = (Toolbar) findViewById(R.id.tb1);
setSupportActionBar(toolbar);
webView = (WebView) findViewById(R.id.web5);
WebSettings set = webView.getSettings();
webView.setWebViewClient(new WebViewClient());
webView.setWebChromeClient(new WebChromeClient());
set.setJavaScriptEnabled(true);
set.setJavaScriptCanOpenWindowsAutomatically(true);
set.setLoadWithOverviewMode(true);
set.setUseWideViewPort(true);
set.setDomStorageEnabled(true);
set.setAllowUniversalAccessFromFileURLs(true);
set.setJavaScriptCanOpenWindowsAutomatically(true);
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
final AlertDialog alertDialog = new AlertDialog.Builder(this).create();
final ProgressDialog progressBar = ProgressDialog.show(MyWebV.this, "Please Wait", "Loading...");
webView.requestFocusFromTouch();
webView.setWebViewClient(new WebViewClient()
{
public void onLoadResource (WebView view, String url) {
if (progressBar == null) {
progressBar.setTitle("Please Wait !");
progressBar.setMessage("Loading...");
progressBar.show();
}
}
public void onPageFinished(WebView view, String url) {
try{
if (progressBar.isShowing()) {
progressBar.dismiss();
}
}catch(Exception exception){
exception.printStackTrace();
}
}
});
webView.setWebChromeClient(new WebChromeClient() {
String url = "www.example.com/login.php";
webView.loadUrl(url);
}
#Override
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
webView.saveState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
webView.restoreState(savedInstanceState);
}
#Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.m_MyWebV, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.about1) {
Intent aboutIntent = new Intent(this, About.class);
startActivity(aboutIntent);
return true;
}
else if (id == R.id.set1) {
Intent webIntent = new Intent(this, Settings.class);
startActivity(webIntent);
return true;
}
return super.onOptionsItemSelected(item);
}
}
}
I My Web-view I have Some Menus So When I click on any menu like Setting or About... It is showing But After that When I go back to Home with Option or Back arrow from Action Bar or Option Menu Its Reloading
So I need to login and And check the previous page its difficult for every time.. Can any one suggest me how to freeze web-view or How to prevent reload with the same app menus...
Update
This is my about Us class
public class About extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aboutus);
Toolbar toolbar = (Toolbar) findViewById(R.id.tb3);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.m_about, menu);
/*something*/
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.home) {
Intent mypIntent = new Intent(this, MyWebV.class);
About.this.finish();
startActivity(mypIntent);
return true;
}
else if (id == R.id.about1) {
Intent aboutIntent = new Intent(this, About.class);
About.this.finish();
startActivity(aboutIntent);
return true;
}
return super.onOptionsItemSelected(item);
}
}
so for example if this is action bar back
so When I click on arrow Its reloading the webview.. On device Hardware back I have disabled... on hardware back its fine but... On action bar back its Reloading
I have just performed a test using two activities, a MainActivity containing a webView just like yours, and a menu button that opens a second activity (About.java), using the exact same intent that you used in onOptionsItemSelected().
After opening About activity from the menu, if I press my phone's hardware back button, it returns to MainActivity without reloading the contents of the WebView, so it works as you expect.
I think the problem you are experiencing is with the code you use to go back to the main activity. You may be using an Intent to open your main activity again from your secondary activities, causing a new instance of your main activity to be created, triggering onCreate(), and thus re-creating your WebView and reloading the page.
To test if that's the case, you can add some debugging statements inside onCreate() using Log.d() or System.out.println(), to check if it's being called when you try to return to your main activity (MyWebV). If you see your debug messages in the logs, it's because you are not returning to your Main Activity properly.
The way you should close your secondary activities to return to your main activity is calling:
finish()
That method will close current activity and restore the previous activity in the stack (your MyWebV activity in this case), without re-creating it, just calling onStart() and onResume(), which wouldn't re-create your WebView or reload the page.
About us or Setting page code where you used your custom back event or hardware back event.I think you are creating activity again inside your back event which is doesn't require you just need to call finish method your Settings or About us page finish there and Webview page remain same as it is.Thats why i am requesting you post your code of one of page at least i can understand what you did exactly.
public class About extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aboutus);
Toolbar toolbar = (Toolbar) findViewById(R.id.tb3);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.m_about, menu);
/*something*/
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.home) {
finish();
return true;
}
else if (id == R.id.about1) {
Intent aboutIntent = new Intent(this, About.class);
About.this.finish();
startActivity(aboutIntent);
return true;
}
return super.onOptionsItemSelected(item);
}
}
#Override public boolean onOptionsItemSelected(MenuItem item)
{ int id = item.getItemId();
if (id == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
I have an app with tab navigation between fragments. One of these fragments has an option to open a new activity. When I use the built in device back button from this activity it goes back to the tabbed activity with the previous fragment tab selected.
I have added a back button to the action bar of an activity in my app by using:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
and setting the parent activity in the manifest, but this button always navigates back to the first tab of the parent activity, rather than the one that was previously visible.
How can I make this back button behave in the same way as the device back button?
Do something like this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch(id) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
onBackPressed() method:
#Override
public void onBackPressed() {
super.onBackPressed();
}
Handle back event in this manner
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch(id) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
in back press method
#Override
public void onBackPressed() {
Intent intent = new Intent(SecondActivity.this,TabbedActivity.class);
intent.putExtra("IsBack",true);
startActivity(intent);
}
in your tabbed activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs);
if(getIntent().getExtras().getBoolean("IsBack")){
//navigate to your desire fragment
}
}
I have a tabbed Actionbar/viewpager layout with three tabs say A, B, and C. In tab C tab(fragment),I am adding another fragment say fragment D. with
DFragment f= new DFragment();
ft.add(android.R.id.content, f, "");
ft.remove(CFragment.this);
ft.addToBackStack(null);
ft.commit();
I modify actionbar in DFragment's onResume to add up button:
ActionBar ab = getActivity().getActionBar();
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
ab.setDisplayHomeAsUpEnabled(true);
ab.setDisplayShowHomeEnabled(true);
Now in DFragment, when I press hardware(phone) Back button, I return to the original Tabbed(ABC) layout with CFragment selected. How can I achieve this functionality with actionbar up button?
Implement OnBackStackChangedListener and add this code to your Fragment Activity.
#Override
public void onCreate(Bundle savedInstanceState) {
//Listen for changes in the back stack
getSupportFragmentManager().addOnBackStackChangedListener(this);
//Handle when activity is recreated like on orientation Change
shouldDisplayHomeUp();
}
#Override
public void onBackStackChanged() {
shouldDisplayHomeUp();
}
public void shouldDisplayHomeUp(){
//Enable Up button only if there are entries in the back stack
boolean canGoBack = getSupportFragmentManager().getBackStackEntryCount()>0;
getSupportActionBar().setDisplayHomeAsUpEnabled(canGoBack);
}
#Override
public boolean onSupportNavigateUp() {
//This method is called when the up button is pressed. Just the pop back stack.
getSupportFragmentManager().popBackStack();
return true;
}
I got it. just override onOptionsItemSelected in hosting activity and popup the backstack, e.g.
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: {
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
return true;
}
break;
}
}
return super.onOptionsItemSelected(item);
}
Call getActionBar().setDisplayHomeAsUpEnabled(boolean); and getActionBar().setHomeButtonEnabled(boolean); in onBackStackChanged() as explained in an answer below.
If you have one parent activity and want this up button to work as a back button, you can use this code:
add this to the onCreate in your main activity class
getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
int stackHeight = getSupportFragmentManager().getBackStackEntryCount();
if (stackHeight > 0) { // if we have something on the stack (doesn't include the current shown fragment)
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setHomeButtonEnabled(false);
}
}
});
and then add onOptionsItemSelected like so:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getSupportFragmentManager().popBackStack();
return true;
....
}
I generally use this all the time and seems pretty legit
you can go back with up button like back button ;
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
super.onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
I used a combination of Roger Garzon Nieto's and sohailaziz's answers. My app has a single MainActivity, and fragments A, B, C that are loaded into it. My "home" fragment (A) implements OnBackStackChangedListener, and checks the size of the backStack; if it's less than one, then it hides the UP button. Fragments B and C always load the back button (in my design, B is launched from A, and C is launched from B). The MainActivity itself just pops the backstack on UP button tap, and has methods to show/hide the button, which the fragments call:
MainActivity:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
getSupportFragmentManager().popBackStack();
return true;
}
return super.onOptionsItemSelected(item);
}
public void showUpButton() { getSupportActionBar().setDisplayHomeAsUpEnabled(true); }
public void hideUpButton() { getSupportActionBar().setDisplayHomeAsUpEnabled(false); }
fragmentA (implements FragmentManager.OnBackStackChangedListener):
public void onCreate(Bundle savedinstanceSate) {
// listen to backstack changes
getActivity().getSupportFragmentManager().addOnBackStackChangedListener(this);
// other fragment init stuff
...
}
public void onBackStackChanged() {
// enable Up button only if there are entries on the backstack
if(getActivity().getSupportFragmentManager().getBackStackEntryCount() < 1) {
((MainActivity)getActivity()).hideUpButton();
}
}
fragmentB, fragmentC:
public void onCreate(Bundle savedinstanceSate) {
// show the UP button
((MainActivity)getActivity()).showUpButton();
// other fragment init stuff
...
}
I know this question is old, but may be someone (like me) also needs it.
If your Activity extends AppCompatActivity, you can use a simpler (two-step) solution:
1 - Whenever you add a non-home fragment just show the up button, right after commiting the fragment transaction. Like this:
// ... add a fragment
// Commit the transaction
transaction.commit();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
2 - Then when UP button is pressed, you hide it.
#Override
public boolean onSupportNavigateUp() {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
return true;
}
That's it.
This worked for me. Override onSupportNavigateUp and onBackPressed, for example (code in Kotlin);
override fun onBackPressed() {
val count = supportFragmentManager.backStackEntryCount
if (count == 0) {
super.onBackPressed()
} else {
supportFragmentManager.popBackStack()
}
}
override fun onSupportNavigateUp(): Boolean {
super.onSupportNavigateUp()
onBackPressed()
return true
}
Now in the fragment, if you display the up arrow
activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
Clicking on it takes you back the previous activity.
Kotlin:
class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
supportFragmentManager.addOnBackStackChangedListener { setupHomeAsUp() }
setupHomeAsUp()
}
private fun setupHomeAsUp() {
val shouldShow = 0 < supportFragmentManager.backStackEntryCount
supportActionBar?.setDisplayHomeAsUpEnabled(shouldShow)
}
override fun onSupportNavigateUp(): Boolean =
supportFragmentManager.popBackStack().run { true }
...
}
This is a very good and reliable solution: http://vinsol.com/blog/2014/10/01/handling-back-button-press-inside-fragments/
The guy has made an abstract fragment that handles the backPress behaviour and is switching between the active fragments using the strategy pattern.
For some of you there maybe a little drawback in the abstract class...
Shortly, the solution from the link goes like this:
// Abstract Fragment handling the back presses
public abstract class BackHandledFragment extends Fragment {
protected BackHandlerInterface backHandlerInterface;
public abstract String getTagText();
public abstract boolean onBackPressed();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!(getActivity() instanceof BackHandlerInterface)) {
throw new ClassCastException("Hosting activity must implement BackHandlerInterface");
} else {
backHandlerInterface = (BackHandlerInterface) getActivity();
}
}
#Override
public void onStart() {
super.onStart();
// Mark this fragment as the selected Fragment.
backHandlerInterface.setSelectedFragment(this);
}
public interface BackHandlerInterface {
public void setSelectedFragment(BackHandledFragment backHandledFragment);
}
}
And usage in the activity:
// BASIC ACTIVITY CODE THAT LETS ITS FRAGMENT UTILIZE onBackPress EVENTS
// IN AN ADAPTIVE AND ORGANIZED PATTERN USING BackHandledFragment
public class TheActivity extends FragmentActivity implements BackHandlerInterface {
private BackHandledFragment selectedFragment;
#Override
public void onBackPressed() {
if(selectedFragment == null || !selectedFragment.onBackPressed()) {
// Selected fragment did not consume the back press event.
super.onBackPressed();
}
}
#Override
public void setSelectedFragment(BackHandledFragment selectedFragment) {
this.selectedFragment = selectedFragment;
}
}
If you want to go back to your previous activity if this activity has an empty stack of fragments:
This could be useful if you have a MainActivity and you are navigating to e.g. a SettingsActivity with nested prefernceScreens. NavigateUp will pop fragments until you can finish the SettingsActivity to go back to parentActivity/root.
/**
* On actionbar up-button popping fragments from stack until it is empty.
* #return true if fragment popped or returned to parent activity successfully.
*/
#Override
public boolean onSupportNavigateUp() {
//Pop back stack if the up button is pressed.
boolean canGoBack = getSupportFragmentManager().getBackStackEntryCount()>0;
if (canGoBack) {
getSupportFragmentManager().popBackStack();
} else {
finish();
return super.onSupportNavigateUp();
}
return true;
}
Note: setDisplayHomeAsUpEnabled(true); in fragment activities onCreate()