Fragment和DialogFragment之间的通信

19
我正在尝试使用DialogFragment API制作一个Fragment来显示一个Dialog
我的对话框只有一个EditText视图,我想把写在上面的字符串传回给Fragment
我能够从Fragment显示对话框,但是我无法从输入字段中检索字符串返回到我的Fragment
我尝试了两种创建对话框的方式:重写DialogFragment.onCreateView方法并编写整个对话框的视图以及重写DialogFragment.onCreateDialog并使用AlertDialog.Builder使按钮行为更容易编写。
关于对话框将事件传递回对话框的主机的Android文档始终指向Activity而不是Fragment。我试图将其行为概括为我的情况,但我无法做到。
我尝试使用DialogFragment.onAttach回调来获取Activity引用,并在FragmentDialogFrament之间使用接口,这样做可以正常工作,但我无法从Activity中检索Fragment以使其正常工作。
有人能提供一个简短的示例吗?
提前致谢。
2个回答

45
您可以使用FragmentsetTargetFragmentgetTargetFragment方法。您可以将您的Fragment设置为DialogFragment的目标,然后从DialogFragment中检索到对其的引用。

3
非常好用,非常感谢。setTargetFragment 的第二个(可选)参数仅在通过 Activity 时需要,是吗? - JoseLSegura
1
哇,开发文档在这里非常误导人,它说你不应该直接进行片段通信:https://developer.android.com/training/basics/fragments/communicating.html,然而却有一个专门用于此目的的API! - Sam
2
@Sam 我认为这些文档更多地讨论了在多面板布局中不同片段之间的直接通信。考虑一个在横屏模式下显示两个片段,但在纵向模式下仅显示其中一个片段的活动。如果这两个片段直接交互,事情会很快变得混乱(因为您必须编写额外的代码来确定这两个片段是否同时显示)。在这种情况下,通过活动(我们知道无论何时都会存在)会更好。 - Alex Lockwood
2
@Sam 另一方面,对于这个特定的问题来说,原始片段似乎与对话片段紧密耦合,因此使用 setTargetFragmentgetTargetFragment 是有意义的。 - Alex Lockwood
在配置更改的情况下,如果您不创建dialogFragment而是系统为您恢复它(如果在配置更改之前对话框正在显示),setTargetFragment()和getTargetFragment方法是否仍然有效?我认为不会。您需要以某种方式手动设置恢复的dialogFragment的目标fragment,才能使getTargetFragment()方法正常工作。 - Akh
@AKh 目标 Fragment 在配置更改时保留。一切恢复后,您无需再次调用 setTargetFragment - pumpkinpie65

3

您可以使用回调函数。只需在DialogFragment中实现一个“完成”按钮或类似的内容。

所以在您的DialogFragment中,可以这样做:

protected OnDialogClickedListener callback = null;

public interface OnDialogClickedListener {
    public abstract void onDialogClicked(int position);
}

public void setOnDialogClickedListener(OnDialogClickedListener l){
    callback = l;
}

button.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
        callback.onDialogClicked(position);
        dismiss();
    }
});

在您的活动中,可以这样做:
final YourFragment f = YourFragment .newInstance(0);
f.show(ft, "YourFragment ");
f.setOnDialogClickedListener(new OnDialogClickedListener() {
    @Override
    public void onDialogClicked(int position) {
        updateText(position);
        f.dismiss();
    }
});

很容易,但我不想修改Activity类,因为有两个原因:第一,它是一个PreferenceActivity,片段是从XML资源定义中加载的。第二,将两个类之间的关系行为附加到第三个类上非常耦合。我已经使用PreferenceFragment完成了这个操作,但使用“纯”Fragment无法工作。 - JoseLSegura
4
这正是你不应该这样做的方式。你没有尊重片段的生命周期。请参考承认的答案和有关片段通信的官方文档:http://developer.android.com/training/basics/fragments/communicating.html - enl8enmentnow

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