10

我已将 viewpager 添加到包含两个页面的活动中。

在活动的 onCreate 中,我将片段添加到 fragmentAdapter:

public void onCreate(Bundle savedInstanceState)
{
    ......

    FragmentAdapter fragmentAdapter = new FragmentAdapter
    (
        getSupportFragmentManager(),
        new Fragment[]{FragmentGame.builder(id), FragmentComments.builder(id)},
        new String[]{getString(R.string.gameInfo), getString(R.string.comments)}
    );

    ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
    viewPager.setAdapter(fragmentAdapter);

public static FragmentGame builder(long id)
{
    FragmentGame fragmentGame = new FragmentGame();

    // fragmentGame.id = id;

    Bundle bundle = new Bundle();
    bundle.putLong(Constants.EXTRA_ID, id);
    fragmentGame.setArguments(bundle);

    return fragmentGame;
}

第一次创建该活动时,会按预期调用片段的onCreateView 。

奇怪的行为是当屏幕第一次旋转时,片段的onCreateView被调用了两次,但第二次调用只有正确的id,而第一次调用的id为 0。

在第二个屏幕旋转时,onCreateView被调用了 3 次,并且只有最后一个具有 id。

通过更多的屏幕旋转,onCreateView调用增加。

我发现了一些有关片段和屏幕旋转的相关问题,但我无法弄清楚为什么会发生这种情况以及如何以正确的方式进行操作。

- - - 更新 - - -

当我用直接值设置替换 bundle 时,ID 问题得到了解决。

4

2 回答 2

15

如果您不想在方向更改时重新加载片段,请为您在清单文件中加载片段的活动编写以下内容。

<activity
            android:name="your activity name"
            android:configChanges="orientation|screenSize" // add this to your activity
            android:label="@string/app_name">
 </activity>
于 2013-10-07T08:32:45.273 回答
8

每次旋转设备时,您都会创建一个新片段并将其添加到 FragmentManager。

您之前创建的所有片段仍在 FragmentManager 中,因此计数每次增加一。

如果您希望在片段中保留一个值,则需要将其存储在参数中,否则当系统重新创建片段时,它包含的任何值都会丢失。

public static FragmentGame builder(long id) {
 Bundle args = new Bundle();
 args.putInt("id", id);
 fragmentGame f = new fragmentGame();
 f.setArguments(args);
}

我怀疑你真的想在旋转设备时检索之前创建的片段,而不是创建一个新片段。使用getSupportFragmentManager().findFragmentById()getSupportFragmentManager().findFragmentByTag()来执行此操作。

编辑:额外代码

    // Add fragment to the manager
    FragmentTransaction trans=getSupportFragmentManager().beginTransaction();
    trans.add(f,"myTag");
    trans.commit();

    // retrieve the fragment
    Fragment f= getSupportFragmentManager().findFragmentByTag("myTag");

只需尝试检索片段,如果值为 null,则创建一个新片段并将其添加到管理器,否则使用检索到的片段。

于 2013-10-07T08:05:57.450 回答