Android ViewPager с вкладкой не поддерживает состояние после поворота экрана

я реализую ViewPager с вкладками, похожими на реализацию, предоставленную Google здесь.

мое приложение имеет следующее поведение. Мой ViewPager имеет 3 "страницы" (fragA, fragB, fragC), и я реализую 3 вкладки поверх ViewPager. Разница между реализацией google и моей заключается в том, что вкладки не используются для навигации между фрагментами. Например, нажатие одной из моих вкладок загружает другой набор данных на видимый фрагмент. Я могу fragA с выбранным tab3, fragB с выбранным tab2 и fragC с выбранным tab1.

проблема в том, когда я поворачиваю экран. Если я на FragmentA при выборе третьей вкладки, когда я поворачиваю экран, я остаюсь в том же фрагменте, но теперь выбрана первая вкладка. Я хочу сохранить ту же вкладку, выбранную при вращении экрана.

это мой класс для управления вкладками:

public class ManagerTabs extends Fragment {

    private TabHost.TabContentFactory mFactory = new TabHost.TabContentFactory() {

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

    public static ManagerTabs newManager() {
        return new ManagerTabs();
    }


    @Override
    public View onCreateView(LayoutInflater inflater,  ViewGroup container,
     Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.datatabs, container, false);
        createTabs();
        createPager();
        return view;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        if (savedInstanceState != null) {
            currentPage = savedInstanceState.getInt("currentPage", currentPage);
            currentTab = savedInstanceState.getInt("currentTab", currentTab);
            mTabHost.setCurrentTab(currentTab);
        }
        mPager.setCurrentItem(currentPage);
    }

    private void createPager() {
        mPager = (ViewPager) view.findViewById(R.id.datapager);
        pagerAdapter = new PagerAdapter(getChildFragmentManager());
        mPager.setAdapter(pagerAdapter);

        IconPageIndicator indicator = (IconPageIndicator) rootView.findViewById(R.id.indicator);
        indicator.setViewPager(pager);
        indicator.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                currentTab = mTabHost.getCurrentTab();

                currentPage = mPager.getCurrentItem();

                switch (currentPage) {
                case 0:
                    ((FragmentA) pagerAdapter.getCurrentFragment(currentPage)).getData(currentTab);
                    break;
                case 1:
                    ((FragmentB) pagerAdapter.getCurrentFragment(currentPage)).getData(currentTab);
                    break;
                case 2:
                    ((FragmentC) pagerAdapter.getCurrentFragment(currentPage)).getData(currentTab);
                    break;
                }
            }
        });
    }

    private void createTabs() {

        mTabHost = (TabHost) view.findViewById(android.R.id.tabhost);
        mTabHost.setup();

        mTabHost.addTab(mTabHost.newTabSpec(getString(R.string.day))setIndicator(getString(R.string.day)).setContent(mFactory));
        mTabHost.addTab(mTabHost.newTabSpec(getString(R.string.month)).setIndicator(getString(R.string.month)).setContent(mFactory));
        mTabHost.addTab(mTabHost.newTabSpec(getString(R.string.year)).setIndicator(getString(R.string.year)).setContent(mFactory));

        mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
            public void onTabChanged(String tag) {
                currentTab = mTabHost.getCurrentTab();
                currentPage = mPager.getCurrentItem();
                switch (currentPage) {
                case 0:
                    ((FragmentA) pagerAdapter.getCurrentFragment(currentPage)).getData(currentTab);
                    break;
                case 1:
                    ((FragmentB) pagerAdapter.getCurrentFragment(currentPage)).getData(currentTab);
                    break;
                case 2:
                    ((FragmentC) pagerAdapter.getCurrentFragment(currentPage)).getData(currentTab);
                    break;
                }
            }
        });
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("currentPage", mPager.getCurrentItem());
        outState.putInt("currentTab", mTabHost.getCurrentTab());
    }
}

и это адаптер, который создает фрагменты:

public class PagerAdapter extends FragmentPagerAdapter implements IconPagerAdapter{

    private Fragment[] currentFragment = new Fragment[3];

    public PagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int index) {
        Fragment fragment;
        switch (index) {
        case 0:
            fragment = FragmentA.newInstance();
            break;
        case 1:
            fragment = FragmentB.newInstance();
            break;
        case 2:
            fragment = FragmentC.newInstance();
            break;
        default:
            fragment = null;
            break;
        }

        currentFragment[index] = fragment;

        return fragment;
    }

    @Override
    public int getIconResId(int index) {

        switch (index) {
        case 0:
            return R.drawable.fraga;
        case 1:
            return R.drawable.fragb;
        case 2:
            return R.drawable.fragc;
        default:
            return -1;
        }
    }

    @Override
    public int getCount() {
        return 3;
    }

    public Fragment getCurrentFragment(int currentFrag) {
        return currentFragment[currentFrag];
    }

    public Fragment[] getCurrentFragment() {
        return currentFragment;
    }
}

и, наконец, фрагмент (FragmentA, FragmentB и FragmentC) почти идентичны:

public class FragmentA extends Fragment {

    public static FragmentA newInstance() {
        return new FragmentA();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.datafragment, container, false);

        mTabHost = (TabHost) ((View) container.getParent().getParent()).findViewById(android.R.id.tabhost);

        if (savedInstanceState != null) {
            currentTab = savedInstanceState.getInt("currentTab");
        }
        populateLayout(currentTab);

        return rootView;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("currentTab", currentTab);
    }
}

проблема в том, что все мои onCreateView всегда вызываются дважды, и во второй раз, когда они вызываются, информация теряется. Я отладил и увидел это поведение,

когда я поворачиваю экран, например, во фрагменте и с третьей выбранной вкладкой, это происходит:

01  ManagerTabs -> onSaveInstanceState
02  FragmentA -> onSaveInstanceState
03  ManagerTabs -> onCreateView
04  ManagerTabs -> onViewCreated

в вызове 04 (ManagerTabs - > onViewCreated), mTabHost.setCurrentTab(currentTab); называется, но внутри onTabChanged, Я получаю java.lang.NullPointerException потому что все фрагменты внутри адаптер-ноль.

что я могу сделать, чтобы при повороте экрана я мог поддерживать текущую выбранную вкладку?

1 ответов


после поворота экрана новый экземпляр - это. Но ... --4--> восстанавливает свое состояние и состояние всех фрагментов, которые он содержит. ViewPager не вызывает адаптеры getView() метод. Поэтому Fragment[] currentFragment содержит