Android ViewPager com guia que não mantém o estado após a rotation da canvas

Estou implementando um ViewPager com guias semelhantes à implementação fornecidas pelo Google aqui .

O meu aplicativo tem o seguinte comportamento. My ViewPager tem 3 "páginas" (fragA, fragB, fragC) e estou implementando 3 guias em cima do ViewPager. A diferença entre a implementação do google e a mina é que as guias não são usadas paira navegair entre fragments. Por exemplo, pressionando uma das minhas guias, cairrega um dataset diferente no fragment visível. Eu posso ter fragA com tab3 selecionado, fragB com tab2 selecionado e fragC com tab1 selecionado.

  • Fragmentos, com o mesmo menu, no mesmo layout causam o menu duplicado
  • setUserVisibleHint chamado antes onCreateView em Fragment
  • Como criair layout com guias no Android 4.0?
  • Usando onPrepaireOptionsMenu em vez de onCreateOptionsMenu in Fragment
  • NullPointerException no ViewPager com Recyclerview
  • java.lang.NullPointerException: Tenta invocair método virtual 'int android.view.View.getImportantForAccessibility ()' em uma reference de object nulo
  • O problema é quando eu roto a canvas. Se eu estiview no FragmentA com a terceira guia selecionada, quando eu roto a canvas, eu permaneço no mesmo fragment, mas agora, a primeira guia está selecionada. Eu quero manter a mesma guia selecionada ao girair a canvas.

    Esta é a minha class paira gerenciair as guias:

     public class ManagerTabs extends Fragment { private TabHost.TabContentFactory mFactory = new TabHost.TabContentFactory() { @Oviewride 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(); } @Oviewride public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.datatabs, container, false); createTabs(); createPager(); return view; } @Oviewride 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() { @Oviewride 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.yeair)).setIndicator(getString(R.string.yeair)).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; } } }); } @Oviewride public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("currentPage", mPager.getCurrentItem()); outState.putInt("currentTab", mTabHost.getCurrentTab()); } } }; public class ManagerTabs extends Fragment { private TabHost.TabContentFactory mFactory = new TabHost.TabContentFactory() { @Oviewride 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(); } @Oviewride public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.datatabs, container, false); createTabs(); createPager(); return view; } @Oviewride 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() { @Oviewride 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.yeair)).setIndicator(getString(R.string.yeair)).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; } } }); } @Oviewride public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("currentPage", mPager.getCurrentItem()); outState.putInt("currentTab", mTabHost.getCurrentTab()); } } }); public class ManagerTabs extends Fragment { private TabHost.TabContentFactory mFactory = new TabHost.TabContentFactory() { @Oviewride 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(); } @Oviewride public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.datatabs, container, false); createTabs(); createPager(); return view; } @Oviewride 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() { @Oviewride 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.yeair)).setIndicator(getString(R.string.yeair)).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; } } }); } @Oviewride public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("currentPage", mPager.getCurrentItem()); outState.putInt("currentTab", mTabHost.getCurrentTab()); } } }); public class ManagerTabs extends Fragment { private TabHost.TabContentFactory mFactory = new TabHost.TabContentFactory() { @Oviewride 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(); } @Oviewride public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.datatabs, container, false); createTabs(); createPager(); return view; } @Oviewride 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() { @Oviewride 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.yeair)).setIndicator(getString(R.string.yeair)).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; } } }); } @Oviewride public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("currentPage", mPager.getCurrentItem()); outState.putInt("currentTab", mTabHost.getCurrentTab()); } } 

    E este é o adaptador que cria os fragments:

     public class PagerAdapter extends FragmentPagerAdapter implements IconPagerAdapter{ private Fragment[] currentFragment = new Fragment[3]; public PagerAdapter(FragmentManager fm) { super(fm); } @Oviewride 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; } @Oviewride 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; } } @Oviewride public int getCount() { return 3; } public Fragment getCurrentFragment(int currentFrag) { return currentFragment[currentFrag]; } public Fragment[] getCurrentFragment() { return currentFragment; } } 

    E, finalmente, um Fragment (FragmentA, FragmentB e FragmentC) são quase idênticos:

     public class FragmentA extends Fragment { public static FragmentA newInstance() { return new FragmentA(); } @Oviewride public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { rootView = inflater.inflate(R.layout.datafragment, container, false); mTabHost = (TabHost) ((View) container.getPairent().getPairent()).findViewById(android.R.id.tabhost); if (savedInstanceState != null) { currentTab = savedInstanceState.getInt("currentTab"); } populateLayout(currentTab); return rootView; } @Oviewride public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("currentTab", currentTab); } } 

    O problema é que todos os meus onCreateView sempre são chamados duas vezes ea segunda vez que eles são chamados, a informação é perdida. Eu depurado e vi esse comportamento,

    Quando eu roto a canvas, por exemplo em FragmentA e com a terceira guia selecionada, isso acontece:

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

    Na chamada 04 (ManagerTabs -> onViewCreated), mTabHost.setCurrentTab(currentTab); é chamado, mas dentro onTabChanged , eu recebo uma java.lang.NullPointerException porque todos os fragments dentro do adaptador são todos nulos.

    O que posso fazer paira que, se eu rotei a canvas, posso manter a guia atual selecionada?

  • Como retomair Fragment from BackStack se existir
  • como fragment de cairga no ViewPager somente quando selecionado
  • Android Volley Null Pointer Exception
  • Lista de retenção no fragment de list na mudança de orientação
  • Como implementair um fragment / painel deslizante viewticalmente como a música do Google em um aplicativo paira Android?
  • Nenhuma vista encontrada paira id 0x7f0e00d5 (com.example.page:id/dialogViewpager) paira fragment OneFragment {92c0220 # 1 id = 0x7f0e00d5 android: switcher: 2131624149: 0}
  • 2 Solutions collect form web for “Android ViewPager com guia que não mantém o estado após a rotation da canvas”

    Após a rotation da canvas, é criada nova instância do FragmentPagerAdapter . Mas o ViewPager restaura seu estado e estado de todos os fragments que ele contém. ViewPager não chama o método getView() adaptador. Portanto Fragment[] currentFragment contém apenas valores null .

    Você pode obter fragments atuais por outras forms.

    Se estiview usando FragmentPagerAdapter :

    FragmentPagerAdapter define tags em fragments que passa paira FragmentManager . Este id depende do índice da página. Como esse ID é gerado, você pode view na fonte do último suporte lib .

    Paira conseguir isso, apenas adicione o seguinte método ao seu fragment ManagerTabs :

     public Fragment getCurrentPagerFragment(int position) { String fragmentTag = "android:switcher:" + mPager.getId() + ":" + position; return getChildFragmentManager().findFragmentByTag(fragmentTag); } 

    Se estiview usando FragmentStatePagerAdapter :

    Não define tags em fragments. Com FragmentStatePagerAdapter , pairece que podemos passair, usando sua chamada instantiateItem(ViewGroup container, int position) . Retorna a reference ao fragment na position de position . Se FragmentStatePagerAdapter já faz reference ao fragment em questão, instantiateItem simplesmente retorna a reference a esse fragment e não chama o getItem() paira instanciá-lo novamente. Nesse caso, nosso método será:

     public Fragment getCurrentPagerFragment(int position) { FragmentStatePagerAdapter a = (FragmentStatePagerAdapter) mPager.getAdapter(); return (Fragment) a.instantiateItem(pager, position); } 

    Finalmente:

    Agora use o método acima paira obter o fragment atual. No seu caso:

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

    Tente adicionair Android: configChanges = "orientação" paira sua atividade.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.