My Application has one Activity with a layout (FrameLayout) for many fragments.
At the start of the Application it displays a list of Places (PlacesFragment).
When a Place is clicked, a Fragment that displays a list of cams (CamFragment) is added. Inside this fragment there is also a button "info".
When the user press the "info" button a new fragment (InfoPlaceFragment) that displays information about the place, is added.
Here is a graphical explanation:
I want to be able to go back to "CamFragment(B)" from "InfoPlaceFragment(C)", and to go back to "PlacesFragment(A)" from "CamFragment(B)".
One Question:
1) Is it possible to realize this or an alternative solution is better?
------- EDIT -------
SOLUTION:
In the "MainActivity.java":
onPlaceParse() // This method is called when the data from the server is received:
// Here I create the "PlaceFragment"
fManager = getSupportFragmentManager();
fragmentPlaces = new PlacesFragment();
fManager.beginTransaction()
.replace(R.id.fragment_list_container, fragmentPlaces)
.commit();
onResortSelected // This method is called when the resort is selected
fragmentCams = new CamsFragment();
fManager.beginTransaction()
.replace(R.id.fragment_list_container, fragmentCams)
.addToBackStack(null)
.commit();
onButtonInfoSelected // This method is called when the btn info is selected
fragmentInfo = new InfoResortFragment();
fManager = getSupportFragmentManager();
fManager.beginTransaction()
.replace(R.id.fragment_list_container, fragmentInfo, "Info")
.addToBackStack(null)
.commit();
When you press the back button, if you are in the "Info Fragment" it returns to "PlaceFragment" and if you are in the "CamsFragment" it returns to "PlacesFragment".
This is possible, you need to call addToBackStack(null) in the fragment transactions.
Reference: Providing Proper Back Navigation
When you create your FragmentTransaction that will add/remove/replace (or whatever pattern you are using) the Fragments, just make sure to call addToBackStack(). Then, when the user presses the back button, the system will automatically cycle back through the entries added to the back stack, in reverse order from how they were originally added. No additional work is required on your part! :)
Related
I've been researching a solution to my problem but not a single result fixes my problem.
I have five Java activities. Each activity has five buttons, four to the other activities and one to itself. It's basically just a bar of bottoms at the bottom of the page.
My issue is that let's say I'm in one activity, and then I click that button to the activity again, it opens and loads an entirely new activity. And then when I click back, it shows the previous activity open as I left it. But if I press it ten times, I need to click back ten times. Also, if I switch between each activity twice and I want to click back to main to exit, I need to click back ten times instead of five.
I want it to be such that when I click a button, it opens the activity. If I press the button again, it does nothing if I'm in that activity. And if I'm switching between activities and I repress an activity I already opened, I want that to be brought to the top of the stack from its lower location, not added. So at most, I only want five activities running.
It's a very confusing problem as I see people suggesting to use intent flags, which I'm not sure if I place them in the manifest, which does nothing with I try. And I've seen people suggest using LaunchMode single instance, which also does nothing.
I really think fragments are the best method here. And yes, it's a little tricky but you can use fragments within fragments. For navigating without creating extra instances, I think you might be looking for something along the lines of this:
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if(id == R.id.nav_home){
Fragment newFragment;
FragmentManager fragmentManager = getSupportFragmentManager();
// Look for fragment by tag
Fragment foundFragment = fragmentManager.findFragmentByTag(MAIN_FRAGMENT);
if(foundFragment != null) { //if fragment's already in the backstack
newFragment = foundFragment; //replace fragment with backstack fragment
}else{
newFragment = new MainFragment(); // use a new fragment instance
}
// Add new fragment instance to fragment manager
fragmentManager.beginTransaction()
.replace(R.id.fragment_container, newFragment, MAIN_FRAGMENT)
.addToBackStack(MAIN_FRAGMENT)
.commit();
}
// ...
}
My app has 3 UI levels, each level has its own fragment, A -> B -> C.
I wish to optionally allow my app user to navigate straight to the top level fragment i.e. from C -> A without invoking B.
i.e., I still want to allow the user to go from C->B if they press the back button, but in the C fragment, I have a "Home" button, which takes them directly to A. This is the operation where I want to flush the backstack.
Additionally, I want the user to be able to go from B->A using the back button, hence I'm adding A and B both to the backstack.
I have tried the options from this SO post but in each case, onCreateView gets invoked for each fragment, even if I use fm_.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
Also checked this thread, it seems to recommend using popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
Can anyone please suggest a way to pop the entire backstack without having the onCreateView called on popped fragments?
Dont add backStack line for going from fragment B->C
while going from A->B use
HighlightFragment highlightFragment=new HighlightFragment(FirstReaderScreen.this);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.LL_Fragment, highlightFragment) // LL_Fragment is container
.addToBackStack(null)
.commit();
while going B->C use
HighlightFragment highlightFragment=new HighlightFragment(FirstReaderScreen.this);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.LL_Fragment, highlightFragment)
.commit();
dont add line .addtobackstack(null)
This worked for me
i estimate you're using replace fragment.
try to use begintransaction.hide / show to manage many fragment inside 1 activity if you don want to popback
//on Activity
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(containerId, new FragmentA(), fragmentA.getClass().getSimpleName());
fragmentTransaction.commit();
//inside fragment A to jump fragment without PopBackStack
getFragmentManager().beginTransaction().hide(this).commit();
getFragmentManager().beginTransaction().show(new FragmentB()).commit();
This is working for me when needing to clear the back stack for tab switches in BottomNavigationView
public void clearBackStack() {
int backStackEntryCount = mFragmentActivity
.getSupportFragmentManager()
.getBackStackEntryCount();
for (int i = 0; i < backStackEntryCount; i++) {
mFragmentActivity.getSupportFragmentManager().popBackStack();
}
}
In android Coding I have some doubts.I am working In Paging concepts.
I have two Fragments. One is Master Fragment and another one is Transaction Fragment.
In master one Button is available. That is vendor. If we click the vendor button we can create a new vendor details.
Its work fine to move forward. That is if we click the vendor button the next page is opened. But if return backward by pressing it doesn't work.
By pressing the back button from new vendor creation to vendor it works. But if we press back button from vendor to Pager fragment it does n't work.
Here I have attached the coding and screen shots. Please help me. Thanks in advance.
Screen Shots
Master
Transaction
Vendor
Vendor Creation
The following is the code when we click the backbutton
Fragment fragment = new MainActivity();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frag_act_cont, fragment, "Class Name").commit();
I don't know if I correctly understand your question. Have a look at the Android Developer Page here
To be able to provide proper back navigation you have to add the fragment to the back stack by
getSupportFragmentManager().beginTransaction()
.add(detailFragment, "detail")
// Add this transaction to the back stack
.addToBackStack()
.commit();
When you press back button the onBackPressed method is called that causes activity to finish.Have a look at this post:http://stackoverflow.com/questions/22011751/life-cycle-of-android-activity-after-pressing-back-button
and try this piece of code.On your backpress method do something like this:
#Override
public void onBackPressed() {
super.onBackPressed();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frag_act_cont, "Class Name").commit();
}
I add, show and hide fragments. Each time I add/show a fragment, I hide the previous fragment and add the transaction to the backstack.
When a user presses the back button, a fragment is popped and I would like to have a reference to it.
Why do I need a reference? So I could hide it when the user continues to the next fragment.
So, how do I get a reference to a popped fragment?
EDIT-25-04-2013:
Here's code to explain how to add a new fragment, while hiding the previous one. The question is how to get a reference to the last fragment after it is popped from the backstack (using the back button)?
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.hide(lastFragment);
fragmentTransaction.add(newFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
lastFragment = newFragment;
I use generated tags for each fragment, save the tags in a stack and persist the stack. This way I get hold of every fragment out there - last one in specific.
See the code here.
I am a new Android developer.
In iOS, there is a class called UINavigationController by which I can push a new viewController to stack and go back to the previous view by pushing the "back" button.
[self pushViewController: myViewController animated:YES]
As far as I know, the instance of UINavigationController has a property to hold the controllers. Therefore, all the attributes in each of the controllers are saved as well in the stack.
I am wondering if the Android can do something similar.
Now I have two fragments to simulate the split view as iOS.
I subclass ListFragment to represent the `lsit view* in the left side and the other fragment to represent the item detail in the right side.
When user taps one of the items in the list view it will go to another list.
SecondFragment newFragment = new SecondFragment();
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
getActionBar().setTitle("new items");
transaction.commit();
getActionBar().setDisplayHomeAsUpEnabled(true);
invalidateOptionsMenu();
However, I want to go back to the previous view by clicking the back button.
I realize that I should add the code as follow:
transaction.addToBackStack(null);
However, my application exits after I tap the back button.
If I want to go back, I have to make another Fragment transaction. The problem is, I want to save the content as item list in the ListFragment other than saving it to the MainActivity. It is much easier for me to retrieve the previous list view content from stack.
Is there any way in Android can do something similar in iOS as UINavigationController?