android-fragments 多次调用FragmentTransaction.replace()-方向更改后只有一个调用有效

qmb5sa22  于 2022-11-13  发布在  Android
关注(0)|答案(3)|浏览(162)

我使用下面的代码来填充我的UI,两个片段的容器是用XML定义的FrameLayout。这是第一次调用这段代码,也就是说,当应用程序启动时,它工作正常,我的两个片段都按预期显示。但是,在配置更改(具体来说,方向)后,只有事务中的第一个片段显示。
我不认为这是片段本身的问题,因为如果我颠倒代码,使一个replace在另一个之前调用,或者反之亦然,该片段将被显示。因此,以下面的片段为例,如果我交换mSummary和mDetails的replace调用,则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中,并在重新创建Activity时从Bundle savedInstanceState中恢复它们。我还尝试通过调用commit()将事务分成两部分,然后获取另一个FragmentTransaction对象,但没有任何效果。

7kjnsjlb

7kjnsjlb1#

所以对于任何在后期遇到这个的人...
最后,我创建了一个新的片段示例,并使用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();

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

hec6srdp

hec6srdp2#

这应该能起作用,方向的改变不会影响碎片。,如果你遇到任何问题,请告诉我。

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

        }

}
vzgqcmou

vzgqcmou3#

尝试在android-manifest中使用android:configChanges="orientation|keyboardHidden|screenSize"

注意事项

从Android 3.2开始(API级别13),当设备在纵向和横向之间切换时,“屏幕大小”也会更改。因此,如果您希望在为API级别13或更高级别开发时防止由于方向更改而导致运行时重新启动(如minSdkVersiontargetSdkVersion属性所声明的),则除了“orientation”值之外,还必须包含“screenSize”值。也就是说,必须decalareandroid:configChanges=“orientation|但是,如果您的应用面向API级别12或更低级别,则您的Activity将始终自行处理此配置更改(此配置更改不会重新启动您的Activity,即使在Android 3.2或更高版本的设备上运行时也是如此)。
来源:Documentation
于是,还加 ”|screenSize” 设置为configChanges(如果应用程序面向
API 13及更高版本**)

相关问题