【问题标题】:getChildFragmentManager() on programmatically (dynamically) added Fragments?getChildFragmentManager() 以编程方式(动态)添加片段?
【发布时间】:2012-12-07 06:11:41
【问题描述】:

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

这是我的例子。

我有一个MainActivity、一个OuterFrag和一个InnerFrag。我将通过FragmentManager 动态地将OuterFrag 添加到MainActivity。此外,我还将通过FragmentManager 动态地将InnerFrag 添加到OuterFrag。但我想将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();
    }
}

outer_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&lt;FrameLayout&gt;更改为&lt;fragment&gt;,添加属性android:name="com.example.frag.OuterFrag",并删除MainActivity.java中的第一个getSupportFragmentManager()语句)。它保持正确的层次结构:MainActivity -&gt; OuterFrag -&gt; InnerFrag。但原片段(outer_frag.xml)的文字永远不能被带走。

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

【问题讨论】:

  • 你搞定了吗?我的问题是你什么时候添加InnerFrag,使它与OuterFrag的生命周期无缝匹配?

标签: android android-fragments android-nested-fragment


【解决方案1】:

总之,我想总是在 MainActivity 中引用 OuterFrag。 我希望 OuterFrag 充当占位符来加载不同的 内部碎片。简而言之,我想调用 getChildFragmentManager() OuterFrag,当它以编程方式(动态)添加时。

如果你想要这个,那么让你的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 添加到主活动的代码仍然有效。

【讨论】:

  • 嗨@Luksprog 我遵循了上述方法,并将内部片段添加到外部片段中。但是 OuterFragment 并没有替换内容。它被添加为视图,并且 OuterFragment 中的先前内容也可见。我也尝试过使用 beginTransaction().replace 但操作没有变化。请帮帮我........
  • @KK_07k11A0585 请发布一个新问题,提供有关您的问题的更多详细信息。请记住,片段事务不会替换将添加片段的布局中已经存在的视图。如果您也想替换它,请将这些初始视图放在另一个片段中。
  • @Luksprog 你好,如何将 InnerDetailFrag 添加到 InnerFrag 中?
  • @Luksprog 我如何管理 innerFrag 的后压以使 outerFrag 可见?
  • 是的,如果子片段调用 MenuItems.clear() 将被删除!
【解决方案2】:

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

OuterFrag.java:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    addInnerFrag();
}

【讨论】:

    猜你喜欢
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    相关资源
    最近更新 更多