Pergunta

I have a viewpager in a fragment that works correctly on start up but if reload the fragment by replace() or replace with another fragment then load it again. The viewpager doesn't work correctly. I have 4 tabs in my pager and depending on which tabs was currently selected the other tabs will appear blank. For example if have the first tab selected the first tab will appear blank and the other 3 will work when i reload the viewpager fragment. Or if the third tab was selected the first and fourth tabs appear blank and the second and third tabs work correctly. Not sure if this is related but if don't call removeAllTabs() on destory the tabs appear twice in the actionbar

edit: I know have it so that if I click on the working tabs and wait a bit the views in the viewpager that where blank show up. Could this behavior be a result of the viewpager being nested in a fragment?

 public class ActionBarTabsPager extends SherlockFragment{
ViewPager mViewPager;
TabsAdapter mTabsAdapter;

@Override
protected void initView(Bundle savedInstanceState) {

    final ActionBar bar = getActionBar();
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);

    mTabsAdapter = new TabsAdapter(this, mViewPager);
    mTabsAdapter.addTab(bar.newTab().setText("Simple"),
            CountingFragment.class, null);
    mTabsAdapter.addTab(bar.newTab().setText("List"),
            FragmentPagerSupport.ArrayListFragment.class, null);
    mTabsAdapter.addTab(bar.newTab().setText("Cursor"),
            CursorFragment.class, null);
    mTabsAdapter.addTab(bar.newTab().setText("Another"),
            AnotherFragment.class, null);

    if (savedInstanceState != null) {
        bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
    }
}

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.activity_main, container,
            false);
    mViewPager = (ViewPager) rootView.findViewById(R.id.view_holder);
    initView(savedInstanceState);
    return rootView;
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}

/**
 * This is a helper class that implements the management of tabs and all
 * details of connecting a ViewPager with associated TabHost.  It relies on a
 * trick.  Normally a tab host has a simple API for supplying a View or
 * Intent that each tab will show.  This is not sufficient for switching
 * between pages.  So instead we make the content part of the tab host
 * 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
 * view to show as the tab content.  It listens to changes in tabs, and takes
 * care of switch to the correct paged in the ViewPager whenever the selected
 * tab changes.
 */
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(Activity activity, ViewPager pager) {
        super(activity.getFragmentManager());
        mContext = activity;
        mActionBar = activity.getActionBar();
        mViewPager = pager;
        mViewPager.setAdapter(this);
        mViewPager.setOnPageChangeListener(this);
    }

    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);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        mActionBar.setSelectedNavigationItem(position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        Object tag = tab.getTag();
        for (int i=0; i<mTabs.size(); i++) {
            if (mTabs.get(i) == tag) {
                mViewPager.setCurrentItem(i);
            }
        }
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }
}
 @Override
public void onDestroyView() {
    super.onDestroyView();
    mActionBar.removeAllTabs();
}
}
Foi útil?

Solução

Found the answer: use getChildFragmentManager().

In the above code, this fixes it:

  public TabsAdapter(SherlockFragment frag, ViewPager pager) {
    super(frag.getChildFragmentManager());
    mContext = frag.getActivity();
    mActionBar = mContext.getActionBar();
    mViewPager = pager;
    mViewPager.setAdapter(this);
    mViewPager.setOnPageChangeListener(this);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top