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{
}
}
Related
I have an Activity (A) that contains a ViewPager which calls a Fragment to present information to the user (this Activity A is called from an Activity B). My Fragment contains a VideoView which plays an MP4 with GIF behavior. My problem is when I want to return to Activity B, since when doing a Finish () in the onBackpressed in Activity A, for a few milliseconds the videoView looks over the contents of Activity B.
UPDATE
I discovered that the problem is due to the ViewPage.
It happens that when I'm in position 0, calling the onBackPressed method works everything ok. But when the onBackPressed method is called from another position, closing the Activity momentarily shows the VideoView of the previous position.
#Override
public void onBackPressed() {
if (mViewPager.getCurrentItem() != 0) {
//I don't know what to do here
}
super.onBackPressed();
}
Please finish your call when you Back pressed.
public void onBackPressed() {
if (/--logic--/) {
finish();
}
}
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.
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.
I've had a look at this question-
Call OnResume when Back Button Pressed when using Fragments
I've done the same things, as mentioned in the answers, but neither is onResume called, nor onCreateView. It's a transaction from an activity to a fragment, all of which are a part of a single tab. How can I call a method from the first fragment when back button is pressed on the second fragment?
Code-
Bundle data = new Bundle();
data.putString("q", code);
data.putString("type", type);
data.putString("name", name);
viewPager.setCurrentItem(1);
android.support.v4.app.FragmentTransaction transaction =
getSupportFragmentManager().beginTransaction();
eq equity = new eq();
equity.setArguments(data);
transaction.replace(R.id.root_frame, equity).addToBackStack(null).commit();
The method called when you press the back button is onOptionsItemSelected
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onBackPressed() {
if (yourCondition = true) {
//do something here
} else {
super.onBackPressed();
}
}
But onOptionsItemSelected is called on the parent activity.
I don't know if the back button is required, but I think it's better to implement a callback from one fragment to the other with an Interface and using a custom button not the back button.
fragment life cycle is directly effected by the host's activity life cycle so you gotta take that in consideration anyway did you try to call the method in onPuase() or in onStart() in the fragment that you are heading for after pressing back ? if that didn't work try to reach the emulator back button from if (keyCode == KeyEvent.KEYCODE_BACK) or you can finish() the previous fragment or activity so the back button will get the user no where and create your own back button to redirect the user and replace the method in it using onClick() .
hope that will work for you good luck
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.