Android ViewPager内部片段,如何保留状态?
在我的应用程序中,片段活动包含两个片段,片段A和片段B。片段B是一个包含3个片段的视图页面 在我的活动中,为了防止在配置更改时重新创建片段:Android ViewPager内部片段,如何保留状态?,android,android-fragments,fragmentpageradapter,Android,Android Fragments,Fragmentpageradapter,在我的应用程序中,片段活动包含两个片段,片段A和片段B。片段B是一个包含3个片段的视图页面 在我的活动中,为了防止在配置更改时重新创建片段: if(getSupportFragmentManager().findFragmentByTag(MAIN_TAB_FRAGMENT) == null) { getSupportFragmentManager().beginTransaction().replace(R.id.container, new MainTabFragment(), M
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());
在onview中创建了,但结果是在旋转时,寻呼机内的碎片被移除
您知道如何在寻呼机中正确保持状态吗?您需要做两件事来解决此问题: 1) 您应该使用
onCreate
方法而不是onViewCreated
来实例化LfPagerAdapter
i、 e:
2) 您需要扩展
FragmentStatePagerAdapter
而不是FragmentPagerAdapter
Android将在配置时自动重新创建您的活动,而无需此行Android:configChanges=“keyboardHidden | orientation | screenSize”
在您的清单中,以便您可以处理onConfiguration
更改自己
唯一的方法是在activityFragement中使用onSaveInstanceState()
保存viewPager状态(例如当前位置)和需要保存内容的片段
有关如何保存viewpager的当前位置并在配置中还原它的示例
@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()方法
下面是关于如何保留状态的另一个示例:我通过在instanceState中保存片段状态(以及选定的寻呼机位置)来实现这一点(由于我现在无法访问Eclipse,所以不知道确切的覆盖)。然后在OnCreate(如果在活动中)或OnCreateView()(如果在片段中),我检查它们是否存在,然后重新创建它们。
fragment
s由FragmentManager
自动管理和还原,PagerAdapter
实现旨在保持对它们的持久引用。初始化每个页面时,getItem()
只会被调用一次。@artworkad:似乎片段已被保留。你到底想表演什么?您能再描述一下吗?FragmentPagerAdapter
从不分离片段
s,因此它们像往常一样由FragmentManager
自动管理和保留,并且两个适配器都保持对它们的持久引用。保留片段
实例是没有必要的,事实上,它甚至可能在某些方面干扰保留视图和/或子片段
s的状态的语义。海盗992:那么需要做什么来解决问题呢?什么都没有-一开始就没有问题。如果未保留片段
实例,则应已管理查看页面
和子片段
的状态(尽管您可能需要正确设置以保留当前页面)。@corsair992:未保留或保留?我没有理解你的意思。正如我在第一条评论中所说:“保留片段
实例是没有必要的,事实上,甚至可能在某些方面干扰保留视图
和/或子片段
的语义。”。我说的是setRetainInstance(true)代码>调用片段
初始化代码。实际上,ViewPager
管理当前位置本身的保存和恢复,前提是在视图
状态恢复后在适当的时间设置适配器。我知道这是很久以前的事了,但是@corsair992您能对此进行扩展吗?这听起来正是我所需要的。@D_Steve595:看看最新版本的支持库中的ViewPager
的源代码,它现在似乎应该能够在所有情况下正确处理位置和适配器状态的持久化。你对此有什么问题吗?谢谢你的回复!我最后提出了一个问题,答案如下:
@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)
}
}