В моем приложении есть 3 вкладки, каждая из которых представлена Fragments
. Существует пользовательский FragmentPagerAdapter
, который также реализует ActionBar.TabListener
. Изначально мой FragmentPagerAdapter возвращал новые экземпляры фрагментов в методе public Fragment getItem(int index)
. Кроме того, моя реализация TabListener создавала фрагменты и отображала/прятала их в файле onTabSelected/onTabUnselected
. К сожалению, этот подход мне не подходит, потому что в этом случае каждый фрагмент фактически создается дважды. Я хочу создать его один раз, а затем просто скрыть/показать, когда это необходимо.
Для этого я создал экземпляр своего фрагмента ранее в действии и передал его PagerAdapter:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_tabs_layout);
List<Fragment> fragments = initTabFragments();
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final ActionBar actionBar = getSupportActionBar();
TabsPagerAdapter pagerAdapter = new TabsPagerAdapter(this, getSupportFragmentManager(), fragments, viewPager);
viewPager.setAdapter(pagerAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (int tab_name : tabs) {
Tab tab = actionBar.newTab();
actionBar.addTab(tab.setText(tab_name).setTabListener(pagerAdapter));
}
...
}
private List<Fragment> initTabFragments() {
List<Fragment> fragments = new ArrayList<Fragment>(3);
fragments.add(SherlockFragment.instantiate(this, TabFragment1.class.getName()));
fragments.add(SherlockFragment.instantiate(this, TabFragment2.class.getName()));
fragments.add(SherlockFragment.instantiate(this, TabFragment3.class.getName()));
return fragments;
}
Затем в PagerAdapter я просто возвращаю фрагмент:
@Override
public Fragment getItem(int index) {
return fragments.get(index);
}
Для обработки выбора Tab существует следующий код:
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
int position = tab.getPosition();
String tag = "android:switcher:" + viewPagerId + ":" + position;
Fragment fragment = context.getSupportFragmentManager().findFragmentByTag(tag);
switch (position) {
case 0:
if (fragment == null) {
ft.add(viewPagerId, fragments.get(0), tag);
} else {
// If it exists, simply attach it in order to show it
ft.show(fragments.get(0));
}
break;
}
case 1:
if (fragment == null) {
ft.add(viewPagerId, fragments.get(1), tag);
} else {
// If it exists, simply attach it in order to show it
ft.show(fragments.get(1));
}
break;
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
switch (tab.getPosition()) {
case 0:
ft.hide(fragments.get(0));
break;
case 1:
ft.hide(fragments.get(1));
break;
}
}
В этом случае каждый фрагмент создается один раз. И первая вкладка отображается правильно, но когда я переключаюсь между вкладками, вторая и третья вкладки пусты (просто белый фон). Почему?
Я пытался добавить фрагмент в контейнер android.R.id.content
, но было выдано исключение: Can't change container ID of fragment...
. Я узнал, что это потому, что когда Fragment возвращается в методе getItem
, он добавляется в контейнер viewPager
. Вот почему я использую viewPagerId при добавлении фрагмента в транзакцию.
Любая помощь будет принята с благодарностью.