force ViewPager to call getItem when going up the backstack

十年热恋 提交于 2019-12-08 04:22:01

问题


I'm trying to create an Android application which contains a single activity with a container and a navigation drawer. The initialy empty container loads fragments which has a ViewPager inside a tab layout in which I load a frgment with a FragmentTransaction:

public static void replaceFragmentInContainer(FragmentManager fragmentManager, Fragment fragmentToShow,
        boolean addToBackStack)
{
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    if (addToBackStack)
    {
        transaction.addToBackStack(null);
    }
    transaction.replace(R.id.container, fragmentToShow);
    transaction.commit();
}

The problem I'm facing is with the backstack. When a fragment is added to the backstack and I press the back button, the app does go back to the previous fragment like I want to and I do see the tabs layout itself, but the content of the tabs is empty like there was nothing loaded to that tab. When it happens, I manage to reload the tab's content only when choosing that screen again with the navigational drawer.

After debugging I saw that the pager adapter's getItem method is not getting called when pressing the back button. The adapter itself is FragmentStatePagerAdapter.

I tried overriding the getItemPosition method:

public int getItemPosition(Object object) 
{
    return POSITION_NONE;
}

but that method wasn't called either when pressing the back button so I end up seeing empty tabs.

And this is the tabs adapter which is also the ViewPager adapter:

public static class TabsAdapter extends FragmentStatePagerAdapter implements TabHost.OnTabChangeListener,
        ViewPager.OnPageChangeListener
{
    private final Context mContext;
    private final TabHost mTabHost;
    private final ViewPager mViewPager;
    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

    public TabsAdapter(final FragmentActivity activity, final TabHost tabHost, final ViewPager pager)
    {
        super(activity.getSupportFragmentManager());
        mContext = activity;
        mTabHost = tabHost;
        mViewPager = pager;
        mTabHost.setOnTabChangedListener(this);
        mViewPager.setAdapter(this);
        mViewPager.setOnPageChangeListener(this);
    }

    public ViewPager getViewPager()
    {
        return mViewPager;
    }

    static final class TabInfo
    {
        private final String tag;
        private final Class<?> clss;
        private final Bundle args;

        TabInfo(final String _tag, final Class<?> _class, final Bundle _args)
        {
            tag = _tag;
            clss = _class;
            args = _args;
        }
    }

    static class TabFactory implements TabHost.TabContentFactory
    {
        private final Context mContext;

        public TabFactory(final Context context)
        {
            mContext = context;
        }

        @Override
        public View createTabContent(final String tag)
        {
            final View v = new View(mContext);
            v.setMinimumWidth(0);
            v.setMinimumHeight(0);
            return v;
        }
    }

    public void addTab(final TabHost.TabSpec tabSpec, final Class<?> clss, final Bundle args)
    {
        tabSpec.setContent(new TabFactory(mContext));
        final String tag = tabSpec.getTag();

        final TabInfo info = new TabInfo(tag, clss, args);
        mTabs.add(info);
        mTabHost.addTab(tabSpec);
        notifyDataSetChanged();
    }

    @Override
    public int getCount()
    {
        return mTabs.size();
    }

    @Override
    public Fragment getItem(final int position)
    {
        final TabInfo info = mTabs.get(position);
        return Fragment.instantiate(mContext, info.clss.getName(), info.args);
    }

    // @Override
    // public Object instantiateItem(ViewGroup container, int position)
    // {
    //
    // // Inflate a new layout from the resources.
    // View view = ((Activity) mContext).getLayoutInflater().inflate(
    // R.layout.fragment_single_conversation, container, false);
    // // Add the newly created View to the ViewPager
    // container.addView(view);
    //
    // // Populate the GUI and views now
    // return view;
    // }


    @Override
    public int getItemPosition(Object object)
    {
        return POSITION_NONE;
    }

    @Override
    public void onTabChanged(final String tabId)
    {
        final int position = mTabHost.getCurrentTab();
        mViewPager.setCurrentItem(position);
    }

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

    @Override
    public void onPageSelected(final int position)
    {
        // Unfortunately when TabHost changes the current tab, it kindly
        // also takes care of putting focus on it when not in touch mode.
        // The jerk.
        // This hack tries to prevent this from pulling focus out of our
        // ViewPager.
        final TabWidget widget = mTabHost.getTabWidget();
        final int oldFocusability = widget.getDescendantFocusability();
        widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
        mTabHost.setCurrentTab(position);
        widget.setDescendantFocusability(oldFocusability);
    }

    @Override
    public void onPageScrollStateChanged(final int state)
    {
    }
}

How can this issue be solved?

来源:https://stackoverflow.com/questions/30618497/force-viewpager-to-call-getitem-when-going-up-the-backstack

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!