Reputation: 3273
I have an issue with a ViewPager + FragmentPageAdapter.
Scenario: I have one Activity with inside a Fragment A. Fragment A has a ViewPager with Fragment B1 e Fragment B2. B1 e B2 are the same class, but different data as argument.
Problem: Everything works well at creation time. But when the app goes in background and the process is killed by android, trying to restore the last state, putting the app up again, Fragment B1 e B2 aren't visible in foreground, while Fragment A is. What seems a bit strange is that Fragment B1 e B2 are int the Fragment A's ChildFragmentManager and the are resumed because onStart() and onResume() are called (seen by Log). Moreover the pager is resumed with two pages, but empty or better with nothing visible.
If I understand well how FragmentPagerAdapter works, it should be its responsibility manage its own fragments and how they should be recreated. Moreover to enforce this point, FragmentPagerAdapter doesn't call getItem(int position) when come back from background if already exist a fragment in that position with a specified tag.
...so why I can't see Fragment B1 e B2, but just the Pager empty?
this is my sample code.
FragmentA
@Override
public void onStart() {
super.onStart();
populateViewPager();
}
private void populateViewPager() {
pager.setAdapter(new MyFragmentPageAdapter(getChildFragmentManager()));
indicator.setViewPager(pager);
indicator.notifyDataSetChanged();
}
FragmentPagerAdapter
public class MyFragmentPageAdapter extends FragmentPagerAdapter {
public MyFragmentPageAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return FragmentB.newInstance(position);
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
String title = "";
if (position == 0)
title = "Fragment B1";
else if (position == 1)
title = "Fragment B2";
return title;
}
}
Fragment B
public static FragmentB newInstance(int position) {
FragmentB f = new FragmentB();
Bundle b = new Bundle();
b.putInt(POSITION_IN_PAGER_ARGUMENT, position);
f.setArguments(b);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
Log.d(TAG, "onCreateView");
View root = inflater.inflate(R.layout.fragment_b_layout, container, false);
empty = (TextView) root.findViewById(R.id.empty);
list = (ListView) root.findViewById(R.id.list);
return root;
}
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart");
populateListView(loadData());
}
@Override
public void onStop() {
super.onStop();
}
}
Upvotes: 11
Views: 3975
Reputation: 81
use FragmentStatePagerAdapter instead of FragmentPagerAdapter. It worked for me. But there will be memory issues (only while screen orientation change) if your ViewPager has lots of views to display.
Upvotes: 8
Reputation: 6485
Here is my PagerDadapter with tabs maybe it can help you a little :
public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
/**
* methode qui construit un onglet
*
* @param tab
* @param clss
* @param args
*/
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
((SherlockFragmentActivity) mContext).supportInvalidateOptionsMenu();
}
public void onPageScrollStateChanged(int state) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
//
// force l'appel de onOptionMenuPrepared
((SherlockFragmentActivity) mContext).supportInvalidateOptionsMenu();
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
Upvotes: 0