android - 无法更改 fragment 的容器 ID

标签 android android-viewpager fragment fragmentpageradapter

我有一个可用的应用程序,我正尝试根据 Android 文档通过扩展不同的布局来优化它以在平板电脑上使用。

我遇到的问题是,当处于纵向时,我的 View 由 ViewPager 填充,我的两个重要 fragment 及其适配器中的数据。在横向时, View 由相同的两个 fragment 填充,但在一个布局中并排放置,而不是在 ViewPager 中。我将 fragment 保存在 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();
    }
}

我应该提到这些 fragment 是嵌套的,因为我的主要 Activity 实际上是 fragment 本身。从 4.2 开始,我相信这不应该成为问题,但我对生命周期不是 100% 的了解。我的 View 是这样填充的:

@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:无法更改 fragment SummaryFragment 的容器 ID{40dd1800 #1 id=0x7f0b004a android:switcher:2131427400:0}:现在是 2131427402 2131427400

我不完全确定这是做我想做的事情的最佳方式——但是将 fragment 保存到一个包中并检索它们是我在 Google IO 2013 源代码中发现的一个技巧,所以我希望它至少是部分正确。

最佳答案

我找到了解决方案。对于纵向和横向模式,我使用 ViewPager,但我在页面适配器方法中进行了重写:

public float getPageWidth(int position)

在正常状态下,此方法返回 1.0f 并且 ViewPager 显示一页,但当方法返回 0.5f 时 - 两页。 在纵向模式下设置 PAGE_WIDTH_FULL_SCREEN,在横向模式下设置 PAGE_WIDTH_HALF_SCREEN,当您在 Activity 中创建适配器时。 下面是覆盖公共(public)方法的示例代码:

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();
}
}

关于android - 无法更改 fragment 的容器 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18179483/

相关文章:

android - 在 Android 的 Fragment 中添加选项卡?

Android:不确定为什么我的 ListView 变得困惑?

android - SPen 将图像转换为文本

Android 错误:IPerf::tryGetService 失败

android - 重新显示 Fragment 时,Fragment 中的 ViewPager 会丢失其内容

android - 数据加载时向 fragment 显示加载标志的最佳方式是什么?

android - 在抽屉导航中管理 fragment

android - 位图的旋转矩阵 - Android

java - 高效读取大量数据

android - 在eclipse上截图