在我的应用程序中,片段活动包含两个片段,片段A和片段B.片段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
中的,但结果是旋转了寻呼机内部的碎片。
如何正确保留寻呼机内的状态?
答案 0 :(得分:27)
您需要做两件事来解决问题:
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
答案 1 :(得分:1)
Android会自动重新创建您的配置活动,而不会显示此行android:configChanges="keyboardHidden|orientation|screenSize"
,以便您可以自行处理onConfiguration
。
唯一的方法是在您的activityFragement中使用onSaveInstanceState()
来保存viewPager状态(例如当前位置)以及需要保存内容的片段
如何保存viewpager的当前位置并将其还原onConfiguration
更改
@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:在片段中恢复使用onActivityCreated()而不是onCreate()方法。
以下是另一个关于如何保留状态的示例:Click me!