片段在方向更改时恢复状态

时间:2013-08-08 23:47:32

标签: android android-fragments screen-orientation android-fragmentactivity onrestoreinstancestate

我必须在我的应用中实施“标准”片段导航(请参阅link)。

问题是当设备处于纵向模式时,应该只显示1个片段,当它旋转到横向模式时,应显示2个片段。

我尝试了两种不同的方式:

1)我只使用1个具有不同纵向和横向布局的活动。

纵向布局xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/main_frame_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

这里的景观布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false"
    android:orientation="horizontal" >

    <FrameLayout
        android:id="@+id/main_frame_fragment_container_left"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <FrameLayout
        android:id="@+id/main_frame_fragment_container_right"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>

活动` onCreate 方法:

    private static ItemsFragment mItemsFragment;
    private static ItemDetailsFragment mItemDetailsFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (mItemsFragment == null) {
            mItemsFragment = ItemsFragment.newInstance();
        }
        if (mItemDetailsFragment == null) {
            mItemDetailsFragment = ItemDetailsFragment.newInstance();
        }

        if (isLandscape()) {
            getSupportFragmentManager().beginTransaction().replace(R.id.main_frame_fragment_container_left, mItemsFragment)
                    .commit();
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit();
        } else {
            getSupportFragmentManager().beginTransaction().replace(R.id.main_frame_fragment_container, mItemsFragment)
                    .commit();
        }
    }

这就是我刷新第二个片段的方式:

Bundle bundle = new Bundle();
bundle.putSerializable(BaseFragment.KEY_BUNDLE_ITEM, response.getItem());
mItemDetailsFragment = ItemDetailsFragment.newInstance(bundle);
if (isLandscape()) {
    getSupportFragmentManager().beginTransaction()
                            .replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit();
} else {
    getSupportFragmentManager().beginTransaction()
                            .replace(R.id.main_frame_fragment_container, mItemDetailsFragment).addToBackStack(null).commit();
}

此外,我保存并恢复片段状态,因此旋转后我的数据不会消失。通常,此代码在我的情况下正常工作。

2)我为第一个活动肖像和横向模式使用了2个活动和相同的布局。

xml布局与之前的横向布局相同:     

    <FrameLayout
        android:id="@+id/main_frame_fragment_container_left"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <FrameLayout
        android:id="@+id/main_frame_fragment_container_right"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>

onCreate 方法(注意,片段实体不是静态的,就像第一种情况一样): private ItemsFragment mItemsFragment;     private ItemDetailsFragment mItemDetailsFragment;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        mItemsFragment = ItemsFragment.newInstance();
        mItemDetailsFragment = ItemDetailsFragment.newInstance();

        getSupportFragmentManager().beginTransaction().replace(R.id.main_frame_fragment_container_left, mItemsFragment)
        .commit();
        getSupportFragmentManager().beginTransaction()
        .replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit();
    }
}

现在,如果设备处于纵向模式,我将启动新的活动:

if (isLandscape()) {
    Bundle bundle = new Bundle();
    bundle.putSerializable(BaseFragment.KEY_BUNDLE_ITEM, response.getItem());
    mItemDetailsFragment = ItemDetailsFragment.newInstance(bundle);
    getSupportFragmentManager().beginTransaction()
        .replace(R.id.main_frame_fragment_container_right, mItemDetailsFragment).commit();
} else {
    Intent intent = new Intent(getApplicationContext(), DetailsActivity.class);
    intent.putExtra(KEY_ITEM, response.getItem());
    startActivity(intent);
}

最后,第二个Activity onCreate 方法:

protected void onCreate(Bundle arg0) {
    super.onCreate(arg0);
    setContentView(R.layout.activity_details);

    if (isLandscape()) {
        finish();
    }

    Item item = (Item) getIntent().getExtras().getSerializable(KEY_ITEM);

    Bundle bundle = new Bundle();
    bundle.putSerializable(BaseFragment.KEY_BUNDLE_ITEM, item);

    ItemDetailsFragment mItemDetailsFragment = ItemDetailsFragment.newInstance(bundle);

    getSupportFragmentManager().beginTransaction()
        .replace(R.id.main_frame_fragment_container, mItemDetailsFragment).commit();
}

当设备旋转到横向模式时,第二个活动结束,我看到我的第一个活动有2个碎片(正如预期的那样)。

问题:

在第一种情况下,我将片段保存为静态变量,因此我不在乎是否在纵向或横向模式下更改第二片段状态(使用相同的片段)。但我不认为将其保存为静态字段是个好主意。

在第二种情况下,我不知道如何同步活动A片段B(风景)和活动B片段B(肖像)。如果我在片段中更改某些内容(我的意思是,切换按钮等)并旋转设备,则应在另一个片段中应用更改。

一般来说,哪种情况更好,如果是第二种,我该如何解决同步问题?或许还有另一种更简单的方法。感谢阅读,希望你能帮帮我:)

1 个答案:

答案 0 :(得分:3)

请关注此伴侣http://developer.android.com/guide/components/fragments.html。不要让片段静止(这很奇怪)