I've implemented something like the below picture:
I have some Tabs and every tab may have some buttons which load some different fragments. In this situation, in Tab 1, Button 1 loads Fragment 1, and Button 2 loads Fragment 2 and each time the Fragments will be re-created. but I want Buttons to load Fragments just once and avoid re-creating next times.
Button 1 current onClick:
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container_root, FragmentOne.newInstance(),"Frag1");
transaction.commit();
How can I save fragments states to avoid reloading every time?
EDIT
The Tab 1 and Tab 2 Fragments are inside a ViewPager so I could not use ViewPager for Fragment 1 and Fragment 2.
Use below code
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.add(R.id.container_root, FragmentOne.newInstance(),"Frag1");
transaction.addToBackStack("Frag1");
transaction.commit();
instead of
FragmentTransaction transaction =
getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container_root, FragmentOne.newInstance(),"Frag1");
transaction.commit();
Problem:
You are trying to replace fragment while adding them via FragmentTransaction. If you need to keep instance of them you need to use transaction.add method.
Caution:
Using this method can overlap fragments. So you need to add backgroundcolor to both fragments and make the parent layout as clickable so that you can interact
you can create your tabs with viewpager
ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
pager.setOffscreenPageLimit(tabsNumber - 1); // e.g. send 2 as parameter for 3 tabs
and save your tab state
Related
So I saw on an android developer site the example implementation of a ViewPager. I saw that ViewPager must be set in an activity class. My application has only one Actvity with about 15 Fragments. The thing I want to do is to use ViewPager only for 3 Fragments, for example:
I go to Fragment 5
When I click back I go to Fragment 1 (this is yet implemented)
When I swipe in Fragment 5 from left to right I go to Fragment 4
When I swipe in Fragment 5 from right to left I go to Fragment 6
When I swipe in the Fragment4/Fragment6 I go back to Fragment 5
When I swipe in the rest of Fragments, nothing happens
Is this even possible with only one Activity containing these all fragments? I will be grateful for any kind of hints.
PS: If that is gonna be helpful answering my question, this is how I switch between fragments now:
MealInfoFragment fragment = new MealInfoFragment();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.addToBackStack(MainActivity.currentFragment);
fragmentTransaction.commit();
Just for the record, I did it by creating a viewpager in a fragment that contains other 3 fragments!
I have an activity with a fragment container layout and in that layout i load a fragment A which has a listview (listview loads data from web). Now on clicking listview item i want to show detail view. For that i am loading another fragment B which is detail fragment. Now to do that first i used
FragmentTransaction ft = ((FragmentActivity) context).getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragmentsContainerLayout, new ScheduleDetailsFragment());
ft.addToBackStack(null);
ft.commit();
But using replace remove the previous fragment A which contain listview and on pressing back it again reloads the onCreateView method of fragment A and its listview data. I want to prevent it from loading fragment A again (or sending call to webserver) on backpress. I want to maintain fragment A state and its listviews scroll position. To do that i used second option which is
FragmentTransaction ft = ((FragmentActivity) context).getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragmentsContainerLayout, new ScheduleDetailsFragment());
ft.addToBackStack(null);
ft.commit();
If i use add() then Fragment B loads on top of Fragment A and Fragment A still visible. It shows both fragments overlapping each other and transparent. I also came across anothe solution which is to use show() and hide() methods. But i dont think that is an efficient way to achieve that. Can anyone suggest an effective solution?
I have a single activity that uses a bunch of different Fragments. I have a TabContainer Fragment that holds a TabLayout which uses a ViewPager to handle tab navigation. Each Tab is its own Fragment.
In one of my tabs, I want to tap and place a fragment on top of my Tabbed fragment. This is meant to be a "details" sort of screen, so I don't want the tabs to be visible. I'm using this and it works as intended:
fragmentTransaction.replace(android.R.id.content, fragmentToDisplay).addToBackStack(null).commit();
Now, when I navigate back, the content in my tab is empty. The content in the tab directly next to that tab is also empty. When I navigate two tabs away, the content is recreated and the normal functionality returns. Why is content not being recreated on the tabs initially when I remove my "detail" fragment?
It turns out that I was simply not passing the correct FragmentManager to the FragmentStatePagerAdapter.
I needed to call getChildFragmentManager() on the Fragment, not getSupportFragmentManager() on the activity.
Thanks to these two posts for the answer:
Fragment in ViewPager not restored after popBackStack
and: Replacing ViewPager with Fragment - Then Navigating Back
I need to replace one list fragment with another one (also list). But they overlaps.
Fragments were added dynamically:
fragmentManager.beginTransaction().replace(R.id.container,
CatalogFragment.newInstance(position + 1)).addToBackStack(null).commit();
and I'm trying to replace this CatalogFragment with LessonFragment in OnFragmentInteractionListener when the item of CatalogFragment's list item clicked like this:
// fragmentManager = getSupportFragmentManager();
// fragmentManager.popBackStack();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_catalog, LessonsFragment.newInstance());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
I've been trying to pop previous item in backStack. Also tried to give the name of backStack of CatalogFragment and then remove it manually. Doesn't work.
Both of fragments are getting displayed at the same time.
I have tried first 10 solutions of google and tried to use standard developer.android's solution of replacement. Fail.
Please help if you know how. Thanks in advance.
P.S. Tell if some more code needed.
From your code, you added CatalogFragment in a layout: R.id.container, but you replace your LessonsFragment in another layout: R.id.fragment_catalog. I think that it's the reason why 2 fragments display at the same time. You should only use 1 Layout view to display fragments with you want only 1 visible.
I am working on an application that contains three tabs and each tab has a fragment associated with it. On certain conditions i have to display child tab within second parent tab. But if that condition is not true then child tabs should not load and the parent tab should load one of the fragment i used in child tabs. For example, i have three fragments FragmentA, FragmentB, and FragmentC. Now if the condition is true then i will display tabs and load FragmentB and FragmentC inside FragmentA using Fragment tab host. But is condition is false i want to display FragmentB in FragmentA.
I tried using Fragment.replace() but it fails.
I think this is not a completely new issue.
You can find an answer here:
Separate Back Stack for each tab in Android using Fragments
Regards
Francesco.
In my intention you should override the onHiddenchange() for fragment A and check the condition over here.
I was able to solve the issue using a common fragment. In FragmentA's onCreateView if condition is true create Tabs using FragmentTabHost and add FragmentB and FragmentC to the tab. If condition is false then inflate a view using
View fragmentView = Inflator.Inflate(R.id.fagment_layout, FragmentB);
FragmentB fragmentB = new FragmentB();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(fragmentView, fragmentB);
transaction.commit();
It worked for me.