对FragmentTransaction.replace()的多次调用 - 只有一个在方向更改后工作

时间:2013-09-09 23:01:05

标签: android android-fragments onconfigurationchanged fragmenttransaction

我使用以下代码用2个片段填充我的UI,容器是用XML定义的FrameLayout。第一次调用此代码,即应用程序启动时,它工作正常,我的两个片段都按预期显示。但是,在配置更改(特别是方向)之后,仅显示事务中的第一个片段。

我不认为这是片段本身的问题,因为如果我反转代码以便在另一个之前调用一个替换,反之亦然,那么将显示该片段。因此,例如使用下面的代码片段作为指导,如果我交换mSummary和mDetails替换调用,那么将显示mDetails而mSummary将不会。

它总是缺少块中的第二个。

// Using tablet layout
} else {
    FragmentManager fm = super.getFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(R.id.summary_container, mSummaryFragment);
    ft.replace(R.id.details_container, mDetailsFragment);
    ft.commit();
}

我将片段保存在onSaveInstanceState中,并在重新创建活动时从Bundle savedInstanceState恢复它们。我还尝试通过调用commit()然后获取另一个FragmentTransaction对象来将事务分成两部分,但没有任何欢乐。

3 个答案:

答案 0 :(得分:1)

所以对于后来遇到这个问题的人来说......

我终于设法通过创建片段的新实例并使用Fragment.SavedState对象恢复它的状态来解决这个问题。所以:

        if (mSummaryFragment.isAdded() && mDetailsFragment.isAdded()) {
            Fragment.SavedState sumState = getSupportFragmentManager().saveFragmentInstanceState(mSummaryFragment);
            Fragment.SavedState detState = getSupportFragmentManager().saveFragmentInstanceState(mDetailsFragment);

            mSummaryFragment = new SummaryFragment();
            mSummaryFragment.setInitialSavedState(sumState);

            mDetailsFragment = new DetailsFragment();
            mDetailsFragment.setInitialSavedState(detState);
        }

        FragmentTransaction ft = mFragmentManager.beginTransaction();

        ft.add(R.id.summary_container, mSummaryFragment);
        ft.add(R.id.details_container, mDetailsFragment);

        ft.commit();

我不明白为什么这种方法有效而旧的方法没有,但这可能对其他人有帮助。

答案 1 :(得分:-1)

尝试在android:configChanges="orientation|keyboardHidden|screenSize"

中使用android-manifest

警告从Android 3.2(API级别13)开始,当设备在纵向和横向之间切换时,“屏幕尺寸”也会发生变化。因此,如果要在开发API级别13或更高级别(由minSdkVersiontargetSdkVersion属性声明)时由于方向更改而阻止运行时重新启动,则必须另外包含“screenSize”值到“取向”的价值。也就是说,你必须decalare android:configChanges =“orientation | screenSize”。但是,如果您的应用程序的目标是API级别12或更低,那么您的活动始终会自行处理此配置更改(即使在Android 3.2或更高版本的设备上运行,此配置更改也不会重新启动您的活动。)

来源:Documentation

因此,如果您的应用程序针对 API 13及以上

,还要将“| screenSize”添加到configChanges

答案 2 :(得分:-1)

这应该有效,方向改变不会影响片段。如果您遇到任何问题,请告诉我。

public class MainActivity extends FragmentActivity {
     Fragment fragment = new Fragment1();
     Fragment fragment2=new Fragment2();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

          FragmentManager fm = super.getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            ft.replace(R.id.frame1, fragment);
            ft.replace(R.id.frame2, fragment2);
            ft.commit();

    }
    public void onSaveInstanceState(Bundle outState){
        getSupportFragmentManager().putFragment(outState,"fragment1",fragment);
        getSupportFragmentManager().putFragment(outState,"fragment2",fragment2);
    }
    public void onRetoreInstanceState(Bundle inState){
        fragment = getSupportFragmentManager().getFragment(inState,"fragment1");
        fragment2 = getSupportFragmentManager().getFragment(inState,"fragment2");

    }
     class Fragment1 extends Fragment{

            @Override
            public void onActivityCreated(Bundle savedInstanceState) {

                super.onActivityCreated(savedInstanceState);
            }
        ListView listView;
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                View view=inflater.inflate(R.layout.summary_view,container,false);
                return view;
            }

            @Override
            public void onViewCreated(View view, Bundle savedInstanceState) {

                super.onViewCreated(view, savedInstanceState);
            }

        }

     class Fragment2 extends Fragment{

            @Override
            public void onActivityCreated(Bundle savedInstanceState) {

                super.onActivityCreated(savedInstanceState);
            }
        ListView listView;
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                View view=inflater.inflate(R.layout.detail_view,container,false);
                return view;
            }

            @Override
            public void onViewCreated(View view, Bundle savedInstanceState) {

                super.onViewCreated(view, savedInstanceState);
            }

        }

}