在DialogFragment中使用FragmentManager和FragmentTransaction

6
问题的要点是:我试图从FragmentActivity启动DialogFragment。此DialogFragment的视图包含一个FrameLayout,我希望用一个Fragment填充它。基本上,FragmentActivity启动DialogFragment,然后DialogFragment用一个Fragment填充它的FrameLayout。我在互联网上搜索了许多教程,并且组合了一些东西(在我的脑海中)应该可以工作。但是,无论我尝试什么,我都不断地遇到错误。目前为止,这是我拥有的:
这是我的FragmentActivity布局(文件名为“activity_interact”):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/activity" >
<Button
        android:id="@+id/btnLaunchDialog"
        style="@style/btn" />

这是我的DialogFragment布局(文件名为“dialog_overview”):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/dialog" >
<FrameLayout
    android:id="@+id/frameDisplay"
    style="@style/frame" />

这是我的Fragment布局(文件名为“fragment_stats”):

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/table" >
<TableRow style="@style/table" >
    <TextView
        style="@style/display"
        android:gravity="right"
        android:text="@string/textStr" />
</TableRow>

这里是我FragmentActivity的Java代码:

public class ActivityInteract extends FragmentActivity implements
    OnClickListener {

Button btnLaunchDialog;

@Override
protected void onCreate(Bundle b) {
    super.onCreate(b);
    setContentView(R.layout.activity_interact);
    btnLaunchDialog = (Button) findViewById(R.id.btnLaunchDialog);
    btnLaunchDialog.setOnClickListener(this);
}

public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btnLaunchDialog:
            FragmentManager fm = getSupportFragmentManager();
            DialogOverview dialogOverview = new DialogOverview();
            dialogOverview.show(fm, "dialog_overview");
            break;
    }
}

这是我的DialogFragment代码:

public class DialogOverview extends DialogFragment implements OnClickListener {

public DialogOverview() {

}
@Override
public View onCreateView(LayoutInflater li, ViewGroup vg, Bundle b) {
    View view = li.inflate(R.layout.dialog_overview, vg);
    FragmentManager fm = getFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.add(R.id.frameDisplay, new FragmentStats());
    ft.commit();
    return view;
}

这是我的Fragment代码:

public class FragmentStats extends Fragment {

@Override
public View onCreateView(LayoutInflater li, ViewGroup vg, Bundle b) {
    View view = li.inflate(R.layout.fragment_stats, vg);
    return view;
}

最后,这里是logcat错误信息:

06-11 10:07:29.382: E/AndroidRuntime(30013): java.lang.IllegalArgumentException: No view found for id 0x7f060003 for fragment FragmentStats{4169c928 #1 id=0x7f060003}

我看到它显示我没有为Fragment创建视图,但我已经创建了...(或者我没有吗?) 我在这里迷失了,任何帮助都将不胜感激。另外,我的做法正确吗? 重新使用FragmentManager会更有效吗?(即从FragmentActivity传递给DialogFragment)
更新:我删除了加载Fragment的代码,现在DialogFragment可以正常显示了。显然(如logcat错误所示),我的Fragment本身存在问题...然而,它与我在互联网上看到的示例相匹配。这让我想知道:以这种方式嵌套片段是否存在问题? FragmentActivity显示一个DialogFragment,该DialogFragment显示一个Fragment,使我想说“我们无法再深入”,但我不知道。我能嵌套更多的Fragments吗?

有人吗?我觉得这没什么问题...也许我漏看了一些非常明显的东西... - user1449018
6
我做了更多的搜索,发现了这篇文章:使用FragmentTransaction与DialogFragment显然,对话框是一个没有容器的视图。 当你尝试加载一个片段到对话框中时,它会寻找容器...但它找不到...而且它不会说“嘿,对于一个对话框来说没有容器,笨蛋!” 而是说你的片段没有视图。 我认为在文档中指出不能将片段添加到对话框片段中会是有用的信息。 无论如何,问题已解决。 我想关闭这个问题,但我是新手... - user1449018
你可以在DialogFragment中使用嵌套片段。请参考我的回答。 - GaRRaPeTa
1个回答

2
实际上,您可以将嵌套的fragment添加到DialogFragment中,但它不能基于包装的对话框。
不要重写onCreateDialog,而是在onCreateView中填充包含将在其中使用Fragment的ViewGroup的View。
这样做的一个后果是,您不能使用包装AlertDialog的DialogFragment - 因此,如果您想要积极和消极按钮,您需要在内容视图中手动创建它们。
此外,请记住,您无法在XML中设置片段。您需要在XML中声明容器视图,并以编程方式执行片段事务。 public class MyDialogFragment extends DialogFragment { [...] }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {



    final View view = inflater.inflate(R.layout.dialog_layout, container);

    if (savedInstanceState == null) {
        final ChildFragment fragment = [...];
        getChildFragmentManager()
                .beginTransaction()
                .replace(R.id.fragment_container, fragment)
                .commit();
    }

    return view;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接