My question is that, i've one activity and one fragment,from activity open that fragment but when i pressed back button it close application.
i try with this code.
for open fragment.
case R.id.button_contact:
Fragment fragment = new FragmentContact();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container,fragment).addToBackStack("Frag1").commit();
break;
for back button.
#Override
public void onBackPressed() {
getSupportFragmentManager().popBackStackImmediate("Frag1",0);
super.onBackPressed();
}
I'm assuming you just want to remove the fragment and have the activity remain?
In that case modify your onBackPressed method to be
#Override
public void onBackPressed() {
if (getSupportFragmentManager().findFragmentByTag("Frag1") != null) {
getSupportFragmentManager().popBackStackImmediate("Frag1",0);
} else {
super.onBackPressed();
}
}
This will remove the fragment from the activity if it is added and if it isn't, then the back button will act as normal and destroy the activity.
Just remove this line from onBackPressed().
getSupportFragmentManager().popBackStackImmediate("Frag1",0);
Its work.
You can do something like this. It will work with your stack:
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
} else {
getSupportFragmentManager().popBackStack();
}
This piece of code will pop the stack if there is any fragment. Otherwise the back button will close the activity
What these two lines are doing:
1). getSupportFragmentManager().popBackStackImmediate("Frag1",0);
As you are adding you fragment in activity backstack, so when you are calling on back press,
it remove fragment from stack, now in your stack activity is left, means stack size is one.
2). super.onBackPressed();
I think you are aware of calling super.onbackpress funcionality, here it will finish
your activity and stack size is 0 now, and app will close immidately if stack size is 0.
so you have to remove super.onbackpress() Method.
Related
I have an activity which uses fragments, when the activity is first created, it displays a first fragment which is not added to back stack cause I don't want to have an empty activity when user presses back.
The fragments loaded after that are added to back stack.
So I have the behavior I want, except: user can open fragments and press back to go back to the previous fragment, up until they reach the first fragment because if they press back at this time, the activity is closed, which I don't want.
So I'd like to know a good solution to prevent back button pressed but only when the first fragment is displayed.
Add .addToBackStack(null) when you call the new fragment from activity.
FragmentTransaction mFragmentTransaction = getFragmentManager()
.beginTransaction();
....
mFragmentTransaction.addToBackStack(null);
-Add onBackPressed() to your activity
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
}
else {
getFragmentManager().popBackStack();
}
}
Solved like this:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount()> 0) {
super.onBackPressed();
}
}
in your activity class add below code in onBackPressed method;
#Override
public void onBackPressed() {
int backstack = getSupportFragmentManager().getBackStackEntryCount();
if (backstack > 0) {
getSupportFragmentManager().popBackStack();
}
else{
super.onBackPressed();
//System.exit(0);
}
}
hope this help.
I have one activity containing one container that will receive 2 fragments.
Once the activity initialises i start the first fragment with:
showFragment(new FragmentA());
private void showFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment, fragment.getTag())
.addToBackStack(fragment.getTag())
.commit();
}
Then when the user clicks on FragmentA, I receive this click on Activity level and I call:
showFragment(new FragmentB());
Now when I press back button it returns to fragment A (thats correct) and when i press again back button it show empty screen (but stays in the same activity). I would like it to just close the app (since the activity has no parent).
There are a lot of posts related with Fragments and backstack, but i can't find a simple solution for this. I would like to avoid the case where I have to check if im doing back press on Fragment A or Fragment B, since i might extend the number of Fragments and I will need to maintain that method.
You are getting blank screen because when you add first fragment you are calling addToBackStack() due to which you are adding a blank screen unknowingly!
now what you can do is call the following method in onBackPressed() and your problem will be solved
public void moveBack()
{
//FM=fragment manager
if (FM != null && FM.getBackStackEntryCount() > 1)
{
FM.popBackStack();
}else {
finish();
}
}
DO NOT CALL SUPER IN ONBACKPRESSED();
just call the above method!
addToBackStack(fragment.getTag())
use it for fragment B only, not for fragment A
I think your fragment A is not popped out correctly, try to use add fragment rather replace to have proper back navigation, however You can check count of back stack using:
FragmentManager fragmentManager = getSupportFragmentManager();
int count = fragmentManager.getBackStackEntryCount();
and you can also directly call finish() in activity onBackPressed() when you want your activity to close on certain fragment count.
I have my MainActivity which has 6 fragments in the Navigation Drawer. Now, whenever I am in any of the 6 fragments and if I press back button, my app is exiting. I want to exit only from the 1st fragment. If I am in other fragments, then if I press back, I want it to come to the 1st fragment and from there if I press back again, then I want to exit.
I have to replace the fragments to the 1st fragment when it is not in the 1st position. I know that. But how exactly can I implement the whole in onBackPressed ?
Please help !! Thanks in advance.
override the onBackPress method and add this code;
public void onBackPressed(){
int count = getFragmentManager().getBackStackEntryCount(); // if stack count is 0, it means no fragment left to pop back stack
if (count = 0) {
finish();
}
}
You can get the fragment name with the instance and we can check weather it is in home fragment or not. Paste this code in the onBackPressed method in main activity class.
Fragment f = getSupportFragmentManager().findFragmentById(R.id.frame_container);
/**
* Compare the instances based on fragment name to change the action bar
*/
if (f instanceof HomeFragment) {
finish();
System.exit(0);
} else {
super.onBackPressed();
}
I have only one activity and multiple fragments in my application.
Two main fragment A(left) and B(right).
Fragment A1 called from A
B1 called from B
B2 called from B1
All fragments have individual back buttons.
So when I press back button of fragment A1, it should go back to A, similarly when Back button from B2 is pressed, B1 appears and from B1 to B and so on.
How to implement this type of functionality?
public void onBackPressed()
{
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.popBackStack();
}
I have implemented the similar Scenario just now.
Activity 'A' -> Calls a Fragment 'A1' and clicking on the menu item, it calls the Fragment 'A2' and if the user presses back button from 'A2', this goes back to 'A1' and if the user presses back from 'A1' after that, it finishes the Activity 'A' and goes back.
See the Following Code:
Activity 'A' - OnCreate() Method:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activityA);
if (savedInstanceState == null) {
Fragment fragInstance;
//Calling the Fragment newInstance Static method
fragInstance = FragmentA1.newInstance();
getFragmentManager().beginTransaction()
.add(R.id.container, fragInstance)
.commit();
}
}
Fragment : 'A1'
I am replacing the existing fragment with the new Fragment when the menu item click action happens:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_edit_columns) {
//Open the Fragment A2 and add this to backstack
Fragment fragment = FragmentA2.newInstance();
this.getFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack(null)
.commit();
return true;
}
return super.onOptionsItemSelected(item);
}
Activity 'A' - onBackPressed() Method:
Since all the fragments have one parent Activity (which is 'A'), the onBackPressed() method lets you to pop fragments if any are there or just return to previous Activity.
#Override
public void onBackPressed() {
if(getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
}
else {
getFragmentManager().popBackStack();
}
}
If you are looking for Embedding Fragments inside Fragments, please refer the link: http://developer.android.com/about/versions/android-4.2.html#NestedFragments
#trueblue's answer got me going with one minor but annoying issue. When there is only one fragment on the backstack and you press back button, that frame is removed and the app remains active with a blank screen. User needed to press back button one more time to exit the app. I modified the original code to the following in order to handle this situation
#Override
public void onBackPressed() {
if(getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
}
else if(getFragmentManager().getBackStackEntryCount() == 1) {
moveTaskToBack(false);
}
else {
getFragmentManager().popBackStack();
}
}
When there is only 1 fragment in the backstack, we are basically telling android to move the whole app to back.
Update (and probably a better answer)
So after doing some more reading around this, I found out that you can add fragment manager transactions to back stack and then android handles back presses automatically and in a desired way. The below code snippet shows how to do that
Fragment fragment; //Create and instance of your fragment class here
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment).addToBackStack(null);
fragmentTransaction.commit();
fragmentTransaction.addToBackStack(null);
The last line shows how you add a transaction to back stack. This solves back press issue for fragments in most situations except for one. If you go on pressing back button, then eventually you will reach a point when there is only one fragment in the back stack. At this point, you will want to do one of the two things
Remove the activity housing the fragment from the back stack of the task in which activity is running. This is because you do not want to end up with a blank activity
If the activity is the only activity in the back stack of the task, then push the task in background.
In my case, it was the later, so I modified the overridden onBackPressed method from my previous answer to look like below
#Override
public void onBackPressed() {
if(getFragmentManager().getBackStackEntryCount() == 1) {
moveTaskToBack(false);
}
else {
super.onBackPressed();
}
}
This code is simpler because it has less logic and it relies on framework than on our custom code. Unfortunately I did not manage to implement code for first situation as I did not need to.
You have to implement your own backstack implementation as explained here.
You can call the popFragments() whenever you click the back button in a fragment and call pushFragments() whenever you navigate from one Fragment to other.
Just Do
getActivity().getFragmentManager().popBackStack();
Try this, Its Work for me.
public void onBackPressed() {
if (mainLayout.isMenuShown()) {
mainLayout.toggleMenu();
} else {
FragmentManager fm = getSupportFragmentManager();
Log.print("back stack entry", fm.getBackStackEntryCount() + "");
if (fm.getBackStackEntryCount() > 1) {
fm.popBackStack();
// super.onBackPressed();
// return;
} else {
if (doubleBackToExitPressedOnce) {
fm.popBackStack();
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Press one more time to exit",
Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce = false;
}
}, 3000);
}
}
}
Back button will traverse in the order, in which Fragments were added to backstack. This is provided as a navigation function by default. Now if you want to go to specific Fragment, you can show it from backstack.
You can handle it by adding tag in the backStack. Check my answer here :
https://stackoverflow.com/a/19477957/1572408
hope it helps
#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 (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){
// replace your fragment here
return true;
}
return false;
}
});
}
// Happy Coding
If you press back image you have to create method first like this
private void Backpresses() {
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.contant_main, new Home()).commit();
}
then you have to call like this when you press back image..
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Backpresses();
}
});
It work fine for me.
In a Fragment i have this:
onPause(){
super.onPause();
if(flag){
getActivity.finish();
}else{
}
}
onResume(){
flag = true;
super.onResume();
}
and there is a Button, on click i set this flag to false:
Button.onClick{
flag = false;
}
The idea is:
when the button is clicked don't finish this Activity. But when device BackButton is pressed finish().
But this logic isn't working. The reason is, when i press BackButton of the device, onPause is not being called.
This is the 4th Fragment in the Activty. So when i press BackButton i can see the 3rd Fragment. Which i don't want to.
I am using this on a API 10 device, But my application uses support library v4.
Thank You.
If you want to close the activity on the back press, then Override the onBackPressed inside the activity as following:
public void onBackPressed() {
Fragment fragment = getSupportFragmentManager().findFragmentByTag("yourfragment");
if (fragment instanceOf YourFragmet) {
finish();
return;
}
super.onBackPressed();
}
If you want to close the activity on the button click, then you can call
Button.onClick{
getActivity().onBackPressed();
}
OR
Button.onClick{
getActivity().finish();
}
If When you are transitioning between Fragments, you call addToBackStack() as part of your FragmentTransaction, then the back button will take you to the fragment on the top of the back stack
Why can't you use onDetach() of Fragment? On Back key pressed, there will be onDetach() called on the fragment to remove that.
#Override
public void onDetach() {
super.onDetach();
if(flag){
getActivity.finish();
}else{
}
}