私のアプリケーションでは、フラグメントアクティビティはフラグメントAとフラグメントBの2つのフラグメントを保持します。フラグメントBは、3つのフラグメントを含むビューページャーです。
私のアクティビティでは、構成の変更時にフラグメントが再作成されないようにするには、次のようにします。
if(getSupportFragmentManager().findFragmentByTag(MAIN_TAB_FRAGMENT) == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.container, new MainTabFragment(), MAIN_TAB_FRAGMENT).commit();
}
フラグメントBのコード:
public class MainTabFragment extends Fragment {
private PagerSlidingTabStrip mSlidingTabLayout;
private LfPagerAdapter adapter;
private ViewPager mViewPager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tab, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
this.adapter = new LfPagerAdapter(getChildFragmentManager());
this.mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
this.mViewPager.setAdapter(adapter);
this.mSlidingTabLayout = (PagerSlidingTabStrip) view.findViewById(R.id.sliding_tabs);
this.mSlidingTabLayout.setViewPager(this.mViewPager);
}
}
アダプターのコード:
public class LfPagerAdapter extends FragmentPagerAdapter {
private static final int NUM_ITEMS = 3;
private FragmentManager fragmentManager;
public LfPagerAdapter(FragmentManager fm) {
super(fm);
this.fragmentManager = fm;
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
Log.d("TEST","TEST");
switch (position) {
case 1:
return FragmentC.newInstance();
case 2:
return FragmentD.newInstance();
default:
return FragmentE.newInstance();
}
}
}
私の問題は、ビューページャーの状態を保持できず、方向の変更時にその子がフラグメント化することです。
明らかに、これはすべてのローテーションで呼び出されます。
this.adapter = new LfPagerAdapter(getChildFragmentManager());
ポケットベル全体が再作成されますよね?結果として
getItem(int position)
すべてのローテーションで呼び出され、フラグメントは最初から作成され、状態が失われます。
return FragmentC.newInstance();
私はこれを次のように解決してみました:
if(this.adapter == null)
this.adapter = new LfPagerAdapter(getChildFragmentManager());
onViewCreated
にありますが、結果として、ローテーション時にページャー内のフラグメントが削除されました。
ページャー内の状態を正しく保持する方法はありますか?
この問題を解決するには、次の2つのことを行う必要があります。
1)onCreate
をインスタンス化するには、onViewCreated
の代わりにLfPagerAdapter
メソッドを使用する必要があります。
つまり:
public class MainTabFragment extends Fragment {
private PagerSlidingTabStrip mSlidingTabLayout;
private LfPagerAdapter adapter;
private ViewPager mViewPager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
this.adapter = new LfPagerAdapter(getChildFragmentManager());
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tab, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
this.mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
this.mViewPager.setAdapter(adapter);
this.mSlidingTabLayout = (PagerSlidingTabStrip) view.findViewById(R.id.sliding_tabs);
this.mSlidingTabLayout.setViewPager(this.mViewPager);
}
}
2)FragmentStatePagerAdapter
の代わりにFragmentPagerAdapter
を拡張する必要があります
Androidは、マニフェストにこの行_Android:configChanges="keyboardHidden|orientation|screenSize"
_がない構成でアクティビティを自動的に再作成するため、onConfiguration
の変更を自分で処理できます。
その場合の唯一の方法は、activityFragementを使用してviewPagerの状態(たとえば現在の位置)を保存することと、データを保存する必要があるフラグメントの両方でonSaveInstanceState()
を使用することです。
ビューページャーの現在の位置を保存して復元する方法の例onConfiguration
change
_ @Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
int position = mViewPager.getCurrentItem();
outState.Int("Key", position );
}
@Override //then restore in on onCreate();
public void onCreated(Bundle savedInstanceState) {
super.onCreated(savedInstanceState);
// do stuff
if (savedInstanceState != null) {
int position= savedInstanceState.getInt("Key");
mViewPager.setCurrentItem(position)
}
}
_
もちろん、これは非常に基本的な例です。
PS:フラグメントで復元するには、onCreate()メソッドの代わりにonActivityCreated()を使用します。
状態を保持する方法の別の例を次に示します: クリックしてください!