我有一个正在运行的应用程序,我正在尝试通过根据Android文档扩展不同的布局来优化平板电脑的使用。
我遇到的问题是,在纵向方向上,我的视图由ViewPager填充,我的两个重要片段及其数据在其适配器中。在横向方向时,View由相同的两个片段填充,但在一个布局中并排放置在ViewPager中。我将片段保存在onSaveInstanceState中,并再次检索它们:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mSummaryFragment != null) {
getFragmentManager().putFragment(outState, TAG_SUMMARY, mSummaryFragment);
}
if (mDetailsFragment != null) {
getFragmentManager().putFragment(outState, TAG_DETAILS, mDetailsFragment);
}
}
检索onCreate ...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mSummaryFragment = (SummaryFragment) getFragmentManager().getFragment(savedInstanceState, TAG_SUMMARY);
mDetailsFragment = (DetailsFragment) getFragmentManager().getFragment(savedInstanceState, TAG_DETAILS);
} else {
mSummaryFragment = new SummaryFragment();
mDetailsFragment = new DetailsFragment();
}
}
我应该提到这些片段是嵌套的,因为我的主要活动实际上是片段本身。从4.2开始,我认为这应该不是问题,但我对生命周期并不是百分之百精明。我的观点如下:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true);
View result = inflater.inflate(R.layout.main, container, false);
ViewPager pager = (ViewPager) result.findViewById(R.id.viewpager);
if (null != pager) {
pager.setAdapter(new PagerAdapter(getFragmentManager(), mUpdater));
} else {
FragmentManager fm = getFragmentManager();
fm.beginTransaction().add(R.id.summary_container, mSummaryFragment).commit();
fm.beginTransaction().add(R.id.details_container, mDetailsFragment).commit();
}
if (savedInstanceState == null) {
Refresh(0,0);
}
return (result);
}
PagerAdapter的getItem方法如下所示:
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return mSummaryFragment;
case 1:
return mDetailsFragment;
}
return null;
}
首次启动时一切正常,但是当方向发生变化时,无论方向改变的方向如何,我都会在logcat中收到此错误(纵向 - >横向,反之亦然):
java.lang.IllegalStateException:无法更改片段SummaryFragment的容器ID {40dd1800#1 id = 0x7f0b004a android:switcher:2131427400:0}:是2131427402现在2131427400
我不完全确定这是做我想要的最佳方式 - 但是将片段保存到捆绑包中并检索它们是我在Google IO 2013源代码中发现的一个技巧,所以我希望它至少是部分正确。
答案 0 :(得分:1)
我找到了解决方案。对于纵向和横向模式,我使用ViewPager,但我在页面适配器方法中重写:
public float getPageWidth(int position)
在正常状态下,此方法返回1.0f并且ViewPager显示一个页面,但是当方法返回0.5f时 - 两个页面。 在纵向模式下设置PAGE_WIDTH_FULL_SCREEN并在横向PAGE_WIDTH_HALF_SCREEN中,在活动中创建适配器时。 示例代码包含以下重写的公共方法:
public class ViewPagerAdapter extends FragmentPagerAdapter {
public static final float PAGE_WIDTH_FULL_SCREEN = 1.0f;
public static final float PAGE_WIDTH_HALF_SCREEN = 0.5f;
private FragmentManager fragmentManager;
private ArrayList<Fragment> fragments;
private float pageWidth = PAGE_WIDTH_FULL_SCREEN;
public ViewPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments) {
super(fm);
this.fragmentManager = fm;
this.fragments = fragments;
}
public void setPageWidth(float pageWidth) {
this.pageWidth = pageWidth;
}
@Override
public float getPageWidth(int position) {
return pageWidth;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
答案 1 :(得分:-3)
您需要先删除它。
if (null != pager) {
pager.setAdapter(new PagerAdapter(getFragmentManager(), mUpdater));
} else {
FragmentManager fm = getFragmentManager();
fm.beginTransaction().remove(mSummaryFragment).add(R.id.summary_container, mSummaryFragment).commit();
fm.beginTransaction().remove(mDetailsFragment).add(R.id.details_container, mDetailsFragment).commit();
}