片段事务和片段创建

时间:2014-11-12 09:01:39

标签: android android-fragments

我很难理解活动中片段的行为。请考虑以下情形:我有一个持有者活动,里面有两个或更多片段。 活动的onCreate方法如下:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_holder);
        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction().add(R.id.container, new Frag1(), "ZZZ").commit();
        }
    }

我在Frag1中有一个按钮,该按钮链接到活动中的callBack:

@Override
    public void bam(String s) {
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
        beginTransaction.replace(R.id.container, new Frag2());
        beginTransaction.addToBackStack(null);
        beginTransaction.commit();
    }

此时,Frag2位于堆栈上,是唯一可见的Fragment。我使用了replace和addToBackStack因为我需要后退导航。 我的问题是当我在Frag2内部旋转屏幕时,活动中的super.onCreate(savedInstanceState)方法调用Frag1的构造函数。

在用户按下后退按钮之前,有没有办法避免调用Frag1的构造函数?

2 个答案:

答案 0 :(得分:0)

您可以在清单文件中设置活动的属性,以便在配置更改时不会破坏您的活动,如下所示:

<activity
        android:name=".HomeActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustPan|adjustResize" >
    </activity>

android:configChanges =&#34; keyboardHidden | orientation | screenSize&#34; ;这些是属性。

或者你可以通过匹配片段的标签进行交叉检查,同时添加或替换片段。为此你需要编码,如下所述:

1)添加片段时添加标签:

    getFragmentManager().beginTransaction().add(R.id.container, new Frag1(), "TAG NAME").commit();

2)然后检查onCreate()活动中的现有片段如下:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_holder);
    fragment1 = getSupportFragmentManager().findFragmentByTag("TAG NAME");
    if(fragment1 == null) { //if fragment null, then add fragment        
        getFragmentManager().beginTransaction().add(R.id.container, new Frag1(), "TAG NAME").commit();
    }
}

答案 1 :(得分:0)

添加到backstack的碎片留在内存中,无法进行垃圾回收。它们被保留为片段的实际引用。重新创建它的原因是因为您仍然拥有片段的实例。您仍然可以使用任何其他对象调用它的方法和字段;它对用户来说根本不可见,并且试图操纵它的视图可能会失败。

如果将片段添加到backstack的唯一目的是导航,这可以通过不将片段放在backstack中来实现,从而让片段的实例脱离内存,然后覆盖onBackPressed ()你可以在活动中重新创建()你的片段1.你可以自由地缓存你需要的任何数据。

backstack的目的是保留碎片状态。当它被写入backstack时,onDestroyView()被调用,但它的viewHierarchy与onSaveInstancestate()一起保存。这样可以保存TextViews中的文本,滚动位置等等。

如果Fragment 1初始化中存在资源密集型内容,您也可以尝试将其移至以后的生命周期事件,例如onResume()。