I have ActionBar Tabs setup. It consists of 4 tabs. Everything is fine until I navigate away from TabbedFragment
and returning back.
I create tabs like this:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final ActionBar actionBar = getActionBar(); tabs = Lists.newArrayList(); tabs.add(new TabDefinition<>("Tab 1")); tabs.add(new TabDefinition<>("Tab 2")); tabs.add(new TabDefinition<>("Tab 3")); tabs.add(new TabDefinition<>("Tab 4")); for (TabDefinition tab : tabs) { actionBar.addTab(actionBar.newTab() .setText(tab.text) .setTag(tab.tag) .setTabListener(this)); } }
And initialize adapter like this:
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.paging_tab_container, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); viewPager = (ViewPager) view.findViewById(R.id.pager); viewPager.setAdapter(new FragmentStatePagerAdapter(getFragmentManager()) { @Override public Fragment getItem(int position) { return tabs.get(position).fragment; } @Override public int getCount() { return tabs.size(); } }); viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { getActionBar().setSelectedNavigationItem(position); } }); viewPager.setCurrentItem(getActionBar().getSelectedNavigationIndex(), true); }
When returning back to TabbedFragment
selected tab and 1 next to it would not have any content. Just empty view. But if I select current + 2 fragment content is loaded. And then returning to that first fragment content is reloaded.
For example I have A, B, C, D tabs. Before leaving TabbedFragment
I had selected tab A. When returning to TabbedFragment
I still am at tab A, but it's empty. So is tab B.
But when selecting tab C it is created and loaded. Returning to tab A it is recreated.
What could be the problem here?
yes...you can use View instead of Fragment in viewpager.
fragment:fragment:1.1. 0 you can just use onPause() and onResume() to determine which fragment is currently visible for the user. onResume() is called when the fragment became visible and onPause when it stops to be visible. To enable this behavior in the first ViewPager you have to pass FragmentPagerAdapter.
Okay so When using a FragmentStatePagerAdapter
your fragments will be destroyed when you navigate anymore than one fragment Away since by default offScreenPageLimit
is set to 1 by default just as mentioned above.
Typically this Class is used for an activity that has a very large set of Fragments
, i.e have to scroll through a large amount of views. If your application does not need more than say 3-4 tabs I would suggest using FragmentPagerAdapter
instead, and then specifying your offScreenPageLimit to something like 3, so if you get to the 4th Tab, all 3 tabs before will still be in memory.
Here is some Sample Code for a project on github that i created illustrating how to dynamically load the fragments if you don't want to add this offScreenPageLimit.
https://github.com/lt-tibs1984/InterfaceDemo/blob/master/src/com/divshark/interfacedemo/InterfaceDemoMain.java
Walk through all this code in this Class, and you will see how I'm dynamically loading the fragments, each time my ViewPager
is slid over. Most notably at the bottom.
You can download this code, and use it as a test base for what you want to do. Try adding the setOffScreenPageLimit(2) in the onCreate() method for the viewPager and notice the different behavior. To check the behavior, edit the text in fragment 1. Navigate Away and navigate back, with this set or not. You will see when it is set, the fragment's text remains what you change it to, since the fragment is never recreated.
Please provide additional questions if you have them.
GoodLuck
UPDATE
private static final String [] fragmentClasses = {"com.example.project.YourFragment1","com.example.project.YourFragment2","com.example.project.YourFragment3"}; viewPager.setAdapter(new FragmentStatePagerAdapter(getFragmentManager()) { @Override public Fragment getItem(int position) { Fragment fragmentAtPosition = null; // $$$$ This is the Important Part $$$$$ // Check to make sure that your array is not null, size is greater than 0 , current position is greater than equal to 0, and position is less than length if((fragmentClasses != null) && (fragmentClasses.length > 0)&&(position >= 0)&& (position < fragmentClasses.length)) { // Instantiate the Fragment at the current position of the Adapter fragmentAtPosition = Fragment.instantiate(getBaseContext(), fragmentClasses[position]); fragmentAtPosition.setRetainInstance(true); } return fragmentAtPosition; } @Override public int getCount() { return fragmentClasses.length; } });
After a while ran into the same problem again, so updating this question. If you're using FragmentStatePagerAdapter
you should provide FragmentManager
via getChildFragmentManager()
instead of getFragmentManager()
. See Issue 55068: ViewPager doesn't refresh child fragments when back navigation via backstack
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With