I am trying to go back to the previous fragments when click back button. If there is no pages available in page stack it should show press back again to exit.
I am trying like this.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
int pageCount = getFragmentManager().getBackStackEntryCount();
if (pageCount != 0) {
this.getFragmentManager().popBackStack();
return true;
}
else
{
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return true;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
}
return super.onKeyDown(keyCode, event);
}
Here I check the page count. But it always showing 0.
I always add this line in all fragment.replace
FragTrans.addToBackStack(null);
Please help me to resolve the problem. When I click the back button It should go to the previous page. If there is no pages is available mean it should show the toast message.
Try it, Use fragment.add instead of fragment.replace. it will allow to
maintain your all Fragments to back stack. If you are using
fragment.replace then it will maintain only one fragment in stack.
Sample Code:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
HelloFragment hello = new HelloFragment();
fragmentTransaction.add(R.id.fragment_container, hello, "HELLO");
fragmentTransaction..addToBackStack("optional tag");
fragmentTransaction.commit();
Related
In my app i have navigation drawer,So i have one MainActivity and rest are fragments. My app is working fine. Whenever i press back button it redirect to previous fragment.it works fine.but what i want is after successful payment i am displaying Successful payment page,on this page when user press back button i want to redirect to HomeFragment,but right now it goes to Placeorder fragment.
#Override
public void onBackPressed() {
if(getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
}
else {
getFragmentManager().popBackStack();
}
}
Override your onBackPress method:
#Override
public void onBackPressed() {
if (fragment != null && fragment.getChildFragmentManager().getBackStackEntryCount() > 0){
fragment.getChildFragmentManager().popBackStack();
}else {
super.onBackPressed();
}
}
One way would be saving previous fragment (previousFragment) variable while opening new fragment and making it null when you are in first or placeholder fragment .... then check value of previousFragment inside onBackPressed method , if null perform exit operation else replace fragment with previousFragment by which you will get back to previous fragment on back press.
You should simulate function as below in abstract class fragment
/**
* Handle "Back" key pressed.
* #return TRUE if the "Back" key pressed was handled. FALSE indicate it's not handled and parent class can handle it.
*/
public abstract boolean onBackPressed()
And in MainActivity, you will handle this function
#Override
public void onBackPressed() {
if (mSelectedFragment != null && mSelectedFragment.onBackPressed()) {
return;
} else {
super.onBackPressed
}
}
inside your onBackPressed() do like this:
#Override
public void onBackPressed() {
if(getSupportFragmentManger.findFragmentByTag("paymentFragment") != null){
//add homeFragment;
}
else{
if(getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
}
else {
getFragmentManager().popBackStack();
}
}
}
you can set some global variable (true when payment is success else false) in Application class and in onbackpressed of your activity just check that variable is true or not.Then in backpressed of your activity call this function.
public void clearBackStack() {
FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() > 0) {
FragmentManager.BackStackEntry first = manager.getBackStackEntryAt(0);
manager.popBackStack(first.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
Use:
fragmentTransaction.replace(R.id.fragment_container, mFeedFragment);
fragmentTransaction.commit();
Don't do this:
fragmentTransaction.addToBackStack(null);
Follow this simple method
declare an integer as
public int count;
initialise this count as count=0 in your main page
now include this in your main activity
#Override
public void onBackPressed() {
if (count == 1) {
if (exit) {
super.onBackPressed();
return;
} else {
Toast.makeText(this, "Press Back again to Exit.", Toast.LENGTH_SHORT).show();
exit = true;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
exit = false;
}
}, 2000);
}
}else {
toolbar.setTitle("Home");
mDrawerLayout.closeDrawers();
count=1;
display(0);
}
}
All I want is to exit the application only when back stack is empty.
One section of my app contains a gallery,in which, when a picture is clicked, a fragment showing the full screen image is opened. When back button is pressed in this full screen image, I want to go back to the gallery fragment. I did this by adding the fragment to back stack.
But in other parts of the application, when back button is pressed, I want to show a toast "Please click BACK again to exit". And when the back button is pressed again, the app closes. How can I do this?
This is what I have done so far:
boolean doubleBackToExitPressedOnce = false;
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0 ){
getFragmentManager().popBackStack();
} else {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
commonTasks.ShowStringMessage("Please click BACK again to exit");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
//super.onBackPressed();
}
}
Obviously, it didn't work.
You can try using getSupportFragmentManager() It has a method which returns array of all the fragments it is containing and you can put the check for its size as following
boolean doubleBackToExitPressedOnce = false;
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getFragments().size() > 0 ){
getSupportFragmentManager().popBackStack();
} else {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
commonTasks.ShowStringMessage("Please click BACK again to exit");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
//super.onBackPressed();
}
}
P.S: you also need to change getSupportFragmentManager() while fragment transection.
Also reffer this link
Why FragmentManager's getBackStackEntryCount() return zero?
You can try something diff. Add Exit code in your Activity's onBackPressed Method, and whenever you get the onBackPressed trigger Just check that is your Gallery Fragment is Active? , if it is then Perform Exit code else Change the Fragment.
//define as field variable
private boolean doubleBackToExit = false;
MyGalleryFragment myFragment = (MyGalleryFragment)getFragmentManager().findFragmentByTag("MY_FRAGMENT");
if (myFragment != null && myFragment.isVisible()) {
if (doubleBackToExit) {
super.onBackPressed();
finishAffinity();
return;
}
this.doubleBackToExit = true;
toastMsg(getResources().getString(R.string.touch_again_to_exit));
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExit = false;
}
}, 2000);
} else {
//Change Layout/Fragment
}
Just Dont forget to Add Tag in Fragment...
fragTrans.replace(android.R.id.content, myFragment, "MY_FRAGMENT");
Hope this will work..!
Try using
super.onBackPressed();
instead of
getFragmentManager().popBackStack();
and let us know about the result.
I want to go back to the previous fragment.I tried many method like addtobackstack(null) and all. But I did not get the solution. My problem is when I click on the back button it goes to the home fragment. But I did not want it. I want that when I click on the back button it go to the previous fragment. Can anyone tell me how can I do this ?
This is my onActivityCreated() method :-
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (i == KeyEvent.KEYCODE_BACK) {
getFragmentManager().popBackStack();
return true;
}
return false;
}
});
}
This is the first Fragment :-
Fragment fragment = new Packages();
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment).addToBackStack(null).commit();
This is the second fragment :-
Fragment fragment = new DeliveryFrag();
mContext.getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment).addToBackStack(null)
.commit();
This is the third Fragment :-
Fragment fragment = new paytm();
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment).addToBackStack(null)
.commit();
I am doing the get the view and apply set onClickListner on it. but the program not enter in this method. I don't know why? Please can anyone tell me what I am doing wrong?
You have to save fragment in stack using fragmentManager.addToBackStack(<fragment tag>).commit();. Then try to do getFragmentManager().popBackStack();
you should call this method in onResume. like this:
#Override
public void onResume() {
super.onResume();
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
getFragmentManager().popBackStack();
return true;
}
return false;
}
});
}
Make all public Fragment like so
public Fragment currentFrag = null;
public Fragment f1 = new Packages();
public Fragment f2 = new DeliveryFrag();
public Fragment f3 = new paytm();
Then, on the button where changing Fragment, fill your null currentFrag with the next one
#Override
public void onClick(View v){
if(currentFrag == null || currentFrag == f1){
//open second fragment code
currentFrag = f2;
}else if(currentFrag == f2){
//open third fragment code
currentFrag = f3;
}
}
then you override the onBackPressed() method in your main activity
#Override
public void onBackPressed()
{
if (currentFrag == f1){
super.onBackPressed() // close the app
}else if(currentFrag == f2){
//calling your first fragment code
currentFrag = null;
}else if(currentFrag == f3){
//calling your second fragment code
currentFrag = f2;
}
}
I hope this helps because even I'm getting a bit confused
worked for me....you can try this..... may help you...
write addToBackStack(null) before commit();
and write following code in your onBackPressed() method.
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 1) {
ApplicationLog.Log(TAG,"IN > 1");
fm.popBackStack(); //will redirect you previous visited fragment
}
else if(fm.getBackStackEntryCount()==1)
{
finish(); //will close application
}
I have an Activity with two Fragments (List & Details), in onCreate(), I start the List Fragment if savedInstance is null like so
public static final int CLIENT_LIST_FRAGMENT = 1;
public static final int CLIENT_DETAILS_FRAGMENT = 2;
private int currentFragment = 0;
if (savedInstanceState == null) {
//On first run, start the list fragment
if (currentFragment == 0) {
ClientListFragment listFrag = new ClientListFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.container_client, listFrag, Constants.CLIENT_LIST_FRAGMENT_TAG)
.commit();
currentFragment = CLIENT_LIST_FRAGMENT;
} else {
switch (currentFragment) {
case CLIENT_LIST_FRAGMENT:
addListFragment();
break;
case CLIENT_DETAILS_FRAGMENT:
addDetailsFragment(0);
break;
}
}
}
And here is the method that add the DetailsFragment and ListFragment as needed
private void addListFragment(){
ClientDetailsFragment listFrag = new ClientDetailsFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.container_client, listFrag, Constants.CLIENT_LIST_FRAGMENT_TAG)
.addToBackStack("details")
.commit();
currentFragment = CLIENT_LIST_FRAGMENT;
}
private void addDetailsFragment(long companyId){
ClientDetailsFragment detailsFrag = ClientDetailsFragment.newInstance(companyId);
getSupportFragmentManager().beginTransaction()
.replace(R.id.container_client, detailsFrag, Constants.CLIENT_DETAILS_TAG)
.addToBackStack(null)
.commit();
currentFragment = CLIENT_DETAILS_FRAGMENT;
}
This works as expected except that when I click the back button from the Details Fragment, instead of taking me back to the List Fragment, it actually finishes the Activity. It goes back to the List Fragment for a split second and then finishes the host Activity and goes back to the calling Activity. How can I stop this behavior, after going through a lot of onBackpress related question on SO here is my overide of the onBackPressed
#Override
public void onBackPressed() {
if (currentFragment == CLIENT_DETAILS_FRAGMENT){
getSupportFragmentManager().popBackStackImmediate();
}else {
super.onBackPressed();
}
}
Thanks
Activity onBackPressed() should be:
For android.support.v4.app.Fragment
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1)
getSupportFragmentManager().popBackStack();
else
finish();
}
For android.app.Fragment
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 1)
getFragmentManager().popBackStack();
else
finish();
}
I usually check whether the current fragment instance belongs to the fragment that invoked onBackPressed(). This code is untested; it's just to give you an idea on how to proceed. I hope you are not calling this.finish() on this Activity.
#Override
public void onBackPressed() {
Fragment fragment = getSuportFragmentManager().findFragmentByTag(Constants.CLIENT_DETAILS_TAG);
if (fragment instanceof ClientDetailsFragment) {
getSupportFragmentManager().popBackStackImmediate();
}
else {
super.onBackPressed();
}
}
Let me know if that helps.
Good Lord, I was chasing the wrong shadow for two days. I was listening, handling and overriding the wrong event.
This SO question saved me Why is onBackPressed() not being called?
And the gist is "onBackPressed() is invoked when user clicks on a hardware back button (or on the 'up' button in the navigation bar), not the button in the action bar. For this one you need to override onOptionsItemSelected() method. Example:"
I was catching this event the fragment and calling getActivity.onBackpressed. When I stopped this, it became obvious to me that the onBackPressed is not being called. Here is my solution, may not be optimal but it works
if (item.getItemId() == android.R.id.home){
if (currentFragment == CLIENT_DETAILS_FRAGMENT){
getSupportFragmentManager().popBackStackImmediate();
currentFragment = CLIENT_LIST_FRAGMENT;
return true;
}
}
if (currentFragment == 0) {
ClientListFragment listFrag = new ClientListFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.container_client, listFrag, Constants.CLIENT_LIST_FRAGMENT_TAG)
.commit();
currentFragment = CLIENT_LIST_FRAGMENT;
}
while changing this add to addToBackStack()
and,
change onBackPressed() like,
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 1) {
MainActivity.this.finish();
}
else {
getFragmentManager().popBackStack();
}
}
Hope, this will work.
I didnt find any solution for my problem.
I got several Fragments (dynamically created), but my Back Button is not working at all,
pressing it will close the App, whatever fragment is "active".
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.itemAdd:
FragmentTransaction tx = getFragmentManager().beginTransaction();
Fragment fragment = new NeuesProduktFrag();
tx.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right,
R.anim.slide_in_left, R.anim.slide_out_right);
tx.replace(R.id.main, fragment);
tx.addToBackStack(null);
tx.commit();
return true;
Everything works fine, but after entering "NeuesProduktFrag" Fragment and pressing Back-Button my App closes. Tried it in different Buttons etc.
Overriding onBackPressed is not needed right ?
addToBackStack should do the trick or not ?
After i struggeled a long time, this is my final Code:
#Override
public void onBackPressed() {
// initialize variables
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
// check to see if stack is empty
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
ft.commit();
}
else {
if (this.lastBackPressTime < System.currentTimeMillis() - 4000) {
Toast.makeText(this, "Nochmal drücken zum Beenden!", 4000).show();
this.lastBackPressTime = System.currentTimeMillis();
} else{
super.onBackPressed();
}
}
}
I used it in my FragmentActivity and added a double tab to close the App finally.
I guess the problem occurs when using getFragmentManager() instead of support library's getSupportFragmentManager() in support library's FragmentActivity. For example, when you want PreferenceFragment and setSupportActionBar() together.
I've solved the problem in my ActionBarActivity by copy-pasting onBackPressed() implementation from android.app.Activity with some changes:
#Override
public void onBackPressed() {
if (getFragmentManager().popBackStackImmediate()) return;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
finish();
else
finishAfterTransition();
}
My code worked changing from FragmentActivity to Activity.
edit: typing error
Press Back Button to exit the application
#Override
public void onBackPressed() {
// initialize variables
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
// check to see if stack is empty
if (fm.getBackStackEntryCount() > 1) {
fm.popBackStack();
ft.commit();
} else {
if (backPressedTime + 2000 > System.currentTimeMillis()) {
backToast.cancel();
finishAffinity();
System.exit(1);
return;
} else {
backToast = Toast.makeText(getBaseContext(), "press back again to exit", Toast.LENGTH_LONG);
backToast.show();
}
backPressedTime = System.currentTimeMillis();
}
}