Sto implementando un ViewPager con schede simili all'implementazione fornita da Google here.ViewPager Android con scheda che non mantiene lo stato dopo la rotazione dello schermo
La mia app ha il seguente comportamento. My ViewPager ha 3 "pagine" (fragA, fragB, fragC) e sto implementando 3 schede in cima al ViewPager. La differenza tra l'implementazione di Google e la mia è che le schede non sono utilizzate per navigare tra i frammenti. Ad esempio, premendo una delle mie schede, carica un diverso set di dati sul frammento visibile. Posso avere fragA con tab3 selezionato, fragB con tab2 selezionato e fragC con tab1 selezionato.
Il problema è quando ruoto lo schermo. Se sono su FragmentA
con la terza scheda selezionata, quando ruoto lo schermo, rimango nello stesso frammento ma ora, la prima scheda è selezionata. Voglio mantenere la stessa scheda selezionata quando si ruota lo schermo.
Questa è la mia classe per la gestione delle schede:
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());
}
}
E questo è l'adattatore che crea i frammenti:
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;
}
}
E, infine, un frammento (fragmenta, FragmentB e FragmentC) sono in modo quasi identico:
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);
}
}
Il problema è che tutta la mia onCreateView
vengono sempre chiamati due volte e la seconda volta che vengono chiamati, l'informazione viene persa. Ho il debug e ho visto questo comportamento,
Quando ho ruotare lo schermo, ad esempio in fragmenta e con la terza scheda selezionata, questo accade:
01 ManagerTabs -> onSaveInstanceState
02 FragmentA -> onSaveInstanceState
03 ManagerTabs -> onCreateView
04 ManagerTabs -> onViewCreated
Nei 04 chiamate (ManagerTabs -> onViewCreated) , mTabHost.setCurrentTab(currentTab);
viene chiamato ma all'interno di onTabChanged
, ottengo uno java.lang.NullPointerException
perché tutti i frammenti all'interno dell'adattatore sono tutti nulli.
Cosa posso fare in modo che se ruoto lo schermo, posso mantenere la scheda selezionata in quel momento?
override di 'onSaveInstanceState' nell'attività e impostare i dati dall'attività –
Ciao. Nessuna fortuna con questo – Favolas
Stai rilasciando tutto collegato all'attività in 'Fragment.onDestroyView()'? – Takhion