Cannot go back to the previous fragment onBackPressed in Android - android

I am absolute beginner to Android. Now I am creating a tutorial project. In my project, there are so many fragments and there is only one activity for that fragment. So when I press the back the button, application always exit. So it does not make any sense for user.
So what I want to do is, I would like to go back to previous fragment if it exists when user press the back button. So I found so many identical question on stackoverflow. All the answers say to do like this. To go back to previous fragment in Activity.
getFragmentManager().popBackStack();
So this is how I override back button listener in my activity:
#Override
public void onBackPressed(){
if ( getFragmentManager().getBackStackEntryCount() > 0)
{
getFragmentManager().popBackStack();
return;
}
}
But it is not working when I press the back button. Is this correct way to do it?

When you replace / add fragment, did you addToBackStack?
Demo :
getFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).replace(R.id.app_bar_main_container, YOUR_FRAGMENT,YOUR_FRAGMENT_TAG).addToBackStack(YOUR_FRAGMENT_TAG).commit();
YOUR_FRAGMENT_TAG needs to be unique for each fragment to be able to go back to all previous fragments.

Related

Android phone built-in back button

I have an activity with two fragments, each fragment has a back button to the previous activity/fragment. Both the back buttons on the fragments work properly. However when i run the app on my android phone and i use the built-in back button to navigate to the previous activity, it displays a blank activity and then when i press the built-in back button again only then does it navigate to the previous activity. The problem is clearly the back burton than built in.Is there a way to solve this???
There is a method in the Activity called onBackPressed() which is called when the device back button is pressed. If you want to control what happens on back press just override it. To remove default onBackPressed action you need to remove the call to super.onBackPressed() and then you control what happens when back button is pressed.
#Override
public void onBackPressed() {
//super.onBackPressed();
// do something here
// or perhaps nothing at all
}

Pressing back on last fragment shows blank Activity shortly before going to previous Activity

I have two Activities and each one has 3-4 Fragments that each replace the other one.
When Activity1,Fragment2 launches the second activity, Activity2,Fragment1 is launched and onBackPressed closes the Activity2 and goes back to Activity1 as normally.
When I'm launching Activity2 from Activity1,Fragment3 though, I want to add Fragment2 to the 2nd activity, which is done via cone in the onCreate method.
However, when the back button is pressed, the fragment disappears for a split second, leaving Activity2 blank on the screen and after that Activity2 is closed, resulting in a visual glitch.
Is there anything I can do to close Activity2 the exact moment (at least at the same visual moment) as when Fragment2 is being closed by the back button?
Thank you.
P.S.: Not adding the Fragment to the backStack seems to close the activity immediately, which is what happens in the first case (expected behavior), but when adding the Fragment to the backStack (as needed for correct operation in the second case) produces the glitch.
Ok, after fighting with the backStack for many days, I decided to skip it, since it does not seem to be working properly, or I'm not understanding it.
The way I did it is on my Activity's onBackPressed i'm checking which fragment is showing and if it's the one that should be the last one (Multiple ones are the "last one") I just finish() the Activity.
#Override
public void onBackPressed() {
MyFragment myFragment = (MyFragment)fragmentManager.findFragmentByTag("MyFragment");
if (myFragment != null && myFragment .isVisible()) {
//if myFragment is visible when the back button is pressed...
finish();
} else {
super.onBackPressed();
}
}
Don't forget to give a name to your fragment in the FragmentManager transaciton. In my case it is "MyFragment".

What does this code mean exactly (involving popBackStackImmediate and pressing back)

This snippet of code:
#Override
public void onBackPressed() {
if( !getFragmentManager().popBackStackImmediate() ) super.onBackPressed();
}
What does this mean exactly? I looked in the docs and it says
"Like popBackStack(int, int), but performs the operation immediately
inside of the call. This is like calling executePendingTransactions()
afterwards."
But I don't know what this means, or what it means to have the negation in front of it, or what super.onBackPressed() is doing.
Returns true if there was something popped, else false.
Basically you are popping your backstack (cleaning the fragments on the history, so when you go back you will not go to the last fragment) and if theres no fragment on the backstack (no fragment on the history) you will do your super.backPressed.
The super.onBackpressed() will execute your activity onBackPressed (even if this code is called from a fragment, as there is no default code to do on your fragment onBackPressed().
If your activity extends a default Android activity it will go back to the last activity, if theres one, os get out of the app, if theres none.
pseudocode:
popBackStack() // clear the fragment history
if (somethingWasPopped) {
super.backPressed() // this will do what i said above
}
Probably the developer who done this was trying to make the user unable to get back to the last fragment when he press back. Like Activity1 -> Activity 2 (frag A -> frag B -> frag C). Now, user is on frag C, he will get back to Activity 1 (when he press back or click on back icon), instead of frag B.

Navigating to Different activities in Android

I have an Android app whose MainActivity contains a list of Chapters/Units let's say.
Now when you click on it, each Unit has "N" number of topics as another list.
When you open any one of them it has the topic explained, and at the bottom there are two "Next" and "Previous" buttons that takes you the next or previous TOPIC respectively.
What happens is
1. I open Unit I, then open Topic 1 and continue till I'm at Topic 8 by pressing "Next" button each time.
2. Now when I press the Back/Up Navigation button I'm being taken to the previous Topic (Topic 7), which I don't want because I'll have to back 8 times to get back to the TOPIC LIST.
What I want is to be taken back to the TOPIC LIST directly instead of going back to previous activity.
How do I achieve it?
The very simple solution to your issue is -
on Previous and next click add finish();
something like this -
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.previous:
goToPreviousTopic();
finish();
break;
case R.id.next:
goToNextTopic();
finish();
break;
}
}
So in background your main activity will be present and in activity stack there will be only one activity after the main activity.
I'm thincking about 2 solutions abbout your your problem (but only if your topics are extends to activity):
First, you can override the onBackPressed method from Activity
#Override
public void onBackPressed() {
// Go to TOPICLIST
}
Second, you change the history of activities to disable the way to back on it.
<activity android:name=".activity.topic.subTopic"
android:noHistory="true"></activity>

Manually Access Android Back Stack

I'm having problems coming up with a solution to this problem.
Basically I have a load of tabs in my ActionBar. When each is touched the fragments from the previous tab are detached and the fragments for the new tab are added using replace (if they haven't been instantiated yet) or attached (if they have). I think I got this method from Google and it was working fine until now.
Example of adding a tab's fragments:
if(tab.getText().equals(context.getString(R.string.title_class_tab))) {
if(browser == null) {
browser = CourseBrowserFragment.newInstance(false);
fragmentTransaction.replace(leftContainerId, browser);
} else {
fragmentTransaction.attach(browser);
}
if(lessonViewer == null) {
lessonViewer = LessonViewerFragment.newInstance(false);
fragmentTransaction.replace(rightContainerId, lessonViewer);
} else {
fragmentTransaction.attach(lessonViewer);
}
}
and removing:
if(tab.getText().equals(context.getString(R.string.title_class_tab))) {
if(browser != null) {
fragmentTransaction.detach(browser);
}
if(lessonViewer != null) {
fragmentTransaction.detach(lessonViewer);
}
}
The problem arises from the layout I need for one of the tabs. Basically it's like the Gmail app. There are two fragments (let's say Panel A and Panel B) and when you push a button Panel A slides out, Panel B slides to Panel A's old position and a new, third one (Panel C) slides in from the right.
I had this working fine but now I've added the sliding-in FragmentTransaction to the back stack so that the user can touch the back button and Panel C will slide back out and Panel A will come back. Again, like Gmail.
Except when the user goes to a different tab this transaction is still on the back stack and executes if the user presses back. The fragments end up in crazy places. What I need to do is remove it from the back stack when the user navigates to a different tab. Is there any way I can do this? FragmentManager doesn't seem to let you manually remove things from the back stack and using the popBackStack() method doesn't just remove the transaction, it executes it. I want to remove it when the user navigates away and put it back when the user returns.
I think I can get a hold of the "Back Stack Entry" for this transaction using "getBackStackEntryAt" but it's not much good if I can't remove it and put it back in place when the user comes back to the tab.
The only possible solution I can think of is not using the back stack and overriding onBackButtonPressed instead. From there I could just do a reverse of the transaction if necessary.
Thanks for any help and sorry if I'm being incoherent.
Not sure if this would qualify as a solution but I ended up just not adding the transaction to the back stack and just doing a fresh transaction when the user swiped or pressed back. The transaction just did the reverse of the original one with animations etc.
The way I managed the back button is I set a boolean to true if I was in the layout showing Panel C. If the user swipes back into the Panel A layout or navigates away the boolean is set to false. I then overrode the onBackButtonPressed method in the Activity and if the boolean was true (ie: we're in the Panel C layout) I run that reverse transaction otherwise I just call super.onBackButtonPressed() (ie: perform standard back button behaviour).

Categories

Resources