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

这是我的示例。

我有一个MainActivity,一个OuterFrag和一个InnerFrag。我将通过OuterFragMainActivity动态添加到FragmentManager中。而且,我还将InnerFrag动态地将OuterFrag添加到FragmentManager中。但是我想将InnerFrag完全添加为OuterFrag的子代,而不是替换OuterFrag并成为MainActivity的新子代。

我想保留此层次结构: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();
    }
}

outside_frag.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<FrameLayout>更改为<fragment>,添加属性android:name="com.example.frag.OuterFrag",并删除getSupportFragmentManager()中的第一个MainActivity.java语句)。并且它保持正确的层次结构:MainActivity -> OuterFrag -> InnerFrag。但是原始片段(outer_frag.xml)的单词永远不会被删除。

总之,我想始终在OuterFrag中引用MainActivity。我希望OuterFrag充当占位符以加载不同的InnerFrag。简而言之,当我以编程方式(动态)添加getChildFragmentManager()时,我想在OuterFrag中调用ojit_code。

最佳答案



如果需要,请使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的布局中具有其他 View 。然后,您的addInnerFrag方法将是:
public void addInnerFrag() {
        getChildFragmentManager().beginTransaction().add(R.id.fragContainer, new InnerFrag()).commit();
        getChildFragmentManager().executePendingTransactions();
}

用于将OuterFrag添加到主 Activity 的代码仍然有效。

10-08 18:51