Този въпрос има някои прилики с:
Фрагментът във ViewPager на Fragment не се презарежда при промяна на ориентацията
Разликата обаче е, че искам да знам как действително се запазват състоянията на фрагментите, тъй като наблюдавам случващи се много странни неща.
Моите наблюдения са следните:
Настройване на ViewPager с FragmentPagerAdapter:
class HomeAdapter extends FragmentPagerAdapter
{
HomeAdapter(FragmentManager manager)
{
super(manager);
}
@Override
public Fragment getItem(int i) {
try {
return (Fragment) mTabs.get(i).getFragmentClass().newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
@Override
public CharSequence getPageTitle(int position) {
return mTabs.get(position).getTitle();
}
@Override
public int getCount() {
return mTabs.size();
}
}
В моята дейност onCreate извиквам:
setContentView(R.layout.activity_home);
mTabs = new ArrayList<>();
mTabs.add(new SlidingTabItem("A", FragmentA.class));
mTabs.add(new SlidingTabItem("B", FragmentB.class));
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mViewPager.setAdapter(new HomeAdapter(getSupportFragmentManager()));
mSlidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setViewPager(mViewPager);
Сега, когато ориентацията на устройството се промени, viewPager пресъздава всичко до променения текст в полетата editText вътре във фрагментите.
За да изясня, това всъщност е поведението, което ИСКАМ, но не го разбирам.
Проверих източника на viewPager и FragmentPagerAdapter. Разбрах, че FragmentPagerAdapter търси FragmentManager, ако вече съществува фрагмент на тази позиция. Ако го направи, той извиква FragmentTransaction.attach(), за да го прикачи отново.
Той също така премахва фрагментите с помощта на FragmentManager.detach()
Доколкото разбирам, това запазва FragmentState във FragmentManager. Но КЪДЕ и КОГА това всъщност се възстановява.
Опитах се да се закача във всеки един метод на жизнения цикъл в моя фрагмент, който съдържа savedInstanceState и да извикам super.X с null като savedInstanceState, но изгледът пак ще бъде възстановен по същия начин.
Възстановеният фрагмент също изглежда игнорира промените в изгледа, направени в onCreateView. Опитах следното:
mMajor = (EditText) contentView.findViewById(R.id.major);
mMajor.setText("123");
който работи при първото създаване на фрагмента. Въпреки това, въпреки че onCreateView всъщност се извиква втори път, тази директива очевидно не прави нищо, тъй като основният editText не се нулира на "123".
Интересното е, че извикването на mMajor.getText().toString() връща нещо като:
[ 01-31 18:29:54.634 18540:29583 I/ActivityManager ]
което също не разбирам. Това ли е защото изгледът не е напълно създаден в този момент?
Така че основният ми въпрос остава. Кога фрагментът всъщност пресъздава своя екземпляр и защо извиква методи на жизнения цикъл, въпреки че не се интересува от резултата и има ли някакъв начин да се открие това, без да се задава променлива на екземпляр при първото създаване на фрагмент?