29

如何在以getChildFragmentManager()编程方式(动态)添加Fragment的 s 上使用(或“我们可以使用”)?

这是我的例子。

我有一个MainActivity,一个OuterFrag,还有一个InnerFrag。我将OuterFrag通过. 而且,我将通过. 但我想完全添加为 的孩子,而不是替换并成为.MainActivityFragmentManagerInnerFragOuterFragFragmentManagerInnerFragOuterFragOuterFragMainActivity

我想保持这个层次结构:MainActivity -> OuterFrag -> InnerFrag. 所以MainActivity总是可以调用OuterFrag。

但不要从这个层次结构改变:MainActivity -> OuterFrag到这个层次结构:MainActivity -> InnerFragMainActivity将丢失OuterFrag.

这是我的示例代码。

MainActivity.java

package com.example.frag;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class MainActivity extends FragmentActivity {

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

        getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, new OuterFrag()).commit();
        getSupportFragmentManager().executePendingTransactions();

        System.out.println("Before: "
                + getSupportFragmentManager().findFragmentById(R.id.frameLayout));

        ((OuterFrag) getSupportFragmentManager().findFragmentById(R.id.frameLayout))
                .addInnerFrag();

        System.out.println("After: "
                + getSupportFragmentManager().findFragmentById(R.id.frameLayout));
    }
}

activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/frameLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
</FrameLayout>

OuterFrag.java

package com.example.frag;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class OuterFrag extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.outer_frag, container, false);
    }

    public void addInnerFrag() {

        getFragmentManager().beginTransaction().replace(this.getId(), new InnerFrag()).commit();
        getFragmentManager().executePendingTransactions();

//        getChildFragmentManager().beginTransaction().add(this.getId(), new InnerFrag()).commit();
//        getChildFragmentManager().executePendingTransactions();
    }
}

外部碎片.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="i am the OUTER frag" />

InnerFrag.java

package com.example.frag;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class InnerFrag extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.inner_frag, container, false);
    }
}

inner_frag.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="i am the INNER frag" />

目前,上述代码可以正常运行。但它实际上正在改变InnerFrag为新的孩子MainActivity。这可以通过两个系统打印输出语句来验证之前:对象和之后:对象已更改。在 中OuterFrag.java,如果getChildFragmentManager()运行语句而不是getFragmentManager()语句,我们将得到以下运行时错误:

12-07 02:29:38.406: E/AndroidRuntime(12051): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.frag/com.example.frag.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f070000 (com.example.frag:id/frameLayout) for fragment InnerFrag{46e32748 #0 id=0x7f070000}

使用getChildFragmentManager()在理论上是正确的。它可以用于非编程方式添加的片段(这意味着将activity_main.xml's更改<FrameLayout><fragment>、添加属性android:name="com.example.frag.OuterFrag"并删除 中的第一条getSupportFragmentManager()语句MainActivity.java)。它保持正确的层次结构:MainActivity -> OuterFrag -> InnerFrag. 但原片断(outer_frag.xml)的文字是永远不能被带走的。

总之,我想总是参考OuterFragMainActivity我想OuterFrag充当一个占位符来加载不同InnerFrag的s。简而言之,当它以编程方式(动态)添加时getChildFragmentManager(),我想调用它。OuterFrag

4

2 回答 2

45

总之,我想总是在 MainActivity 中引用 OuterFrag。我希望 OuterFrag 作为一个占位符来加载不同的 InnerFrags。简而言之,当以编程方式(动态)添加时,我想在 OuterFrag 中调用 getChildFragmentManager()。

如果你想要这个,那么让你OuterFrag有一个容器布局作为它的内容并将任何内容添加InnerFrag到该容器中。将的布局文件OuterFrag是:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
/>

当然,OuterFrag如果需要,您可以在布局中使用其他视图。那么你的addInnerFrag方法将是:

public void addInnerFrag() {
        getChildFragmentManager().beginTransaction().add(R.id.fragContainer, new InnerFrag()).commit();
        getChildFragmentManager().executePendingTransactions();
}

添加OuterFrag到主要活动的代码仍然有效。

于 2012-12-07T06:29:55.800 回答
-1

如果你想addInnerFrag()在你的OuterFrag.java代码中调用,你可以这样做:

OuterFrag.java:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    addInnerFrag();
}
于 2016-06-09T13:33:45.603 回答