我使用DialogFragments的一些事情:从列表中选择项目,输入文本。

将值(即字符串或列表中的项)返回给调用活动/片段的最佳方法是什么?

目前,我正在使调用活动实现驳回监听器,并给予DialogFragment对活动的引用。然后Dialog在activity中调用ondismiss方法,activity从DialogFragment对象中抓取结果。非常混乱,它不能在配置更改(方向更改),因为DialogFragment失去了对活动的引用。

谢谢你的帮助。


当前回答

对于还在阅读这篇文章的人:setTargetFragment()已被弃用。现在建议像这样使用FragmentResultListener API:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setFragmentResultListener("requestKey") { key, bundle ->
        val result = bundle.getString("resultKey")
        // Do something with the result...
    }

    ...

    // Somewhere show your dialog
    MyDialogFragment.newInstance().show(parentFragmentManager, "tag")
}

然后在你的MyDialogFragment中设置结果:

button.setOnClickListener{
    val result = "some string"
    setFragmentResult("requestKey", bundleOf("resultKey" to result))
    dismiss()
}

其他回答

正如你在这里看到的,有一个非常简单的方法来做到这一点。

在你的DialogFragment中添加一个接口监听器:

public interface EditNameDialogListener {
    void onFinishEditDialog(String inputText);
}

然后,添加对该监听器的引用:

private EditNameDialogListener listener;

这将被用来“激活”监听器方法,也用来检查父Activity/Fragment是否实现了这个接口(见下文)。

在“调用”DialogFragment的Activity/FragmentActivity/Fragment中简单地实现了这个接口。

在你的DialogFragment中,你需要在你想要解散DialogFragment并返回结果的地方添加以下内容:

listener.onFinishEditDialog(mEditText.getText().toString());
this.dismiss();

mEditText.getText(). tostring()将被传递回调用Activity。

注意,如果您想返回其他内容,只需更改侦听器所接受的参数。

最后,你应该检查接口是否由父活动/片段实际实现:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    // Verify that the host activity implements the callback interface
    try {
        // Instantiate the EditNameDialogListener so we can send events to the host
        listener = (EditNameDialogListener) context;
    } catch (ClassCastException e) {
        // The activity doesn't implement the interface, throw exception
        throw new ClassCastException(context.toString()
                + " must implement EditNameDialogListener");
    }
}

这种技术非常灵活,即使你还不想结束对话框,也可以回调结果。

我发现了一个简单的方法: 实现这个是你的dialogFragment,

  CallingActivity callingActivity = (CallingActivity) getActivity();
  callingActivity.onUserSelectValue("insert selected value here");
  dismiss();

然后在调用Dialog Fragment的activity中创建相应的函数:

 public void onUserSelectValue(String selectedValue) {

        // TODO add your implementation.
      Toast.makeText(getBaseContext(), ""+ selectedValue, Toast.LENGTH_LONG).show();
    }

祝酒词是为了证明它是有效的。为我工作。

我很惊讶地看到,没有人建议使用本地广播进行DialogFragment到Activity的通信!我发现它比其他建议更简单、更清晰。本质上,您为您的Activity注册侦听广播,并从您的DialogFragment实例发送本地广播。简单。有关如何设置它的一步一步的指南,请参见这里。

好吧,现在回答可能为时已晚,但这是我从DialogFragment中获得结果的方法。非常类似于@brandon的回答。 这里我从一个片段调用DialogFragment,只是把这段代码放在你调用你的对话框的地方。

FragmentManager fragmentManager = getFragmentManager();
            categoryDialog.setTargetFragment(this,1);
            categoryDialog.show(fragmentManager, "dialog");

where categoryDialog是我的DialogFragment,我想调用这之后,在你的DialogFragment的实现中放置这段代码,你在意图中设置你的数据。resultCode的值为1,可以设置或使用system Defined。

            Intent intent = new Intent();
            intent.putExtra("listdata", stringData);
            getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);
            getDialog().dismiss();

现在回到调用片段并实现该方法。在if条件中使用resultCode和requestCode检查数据有效性或结果成功。

 @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);        
        //do what ever you want here, and get the result from intent like below
        String myData = data.getStringExtra("listdata");
Toast.makeText(getActivity(),data.getStringExtra("listdata"),Toast.LENGTH_SHORT).show();
    }

在Kotlin

    // My DialogFragment
class FiltroDialogFragment : DialogFragment(), View.OnClickListener {
    
    var listener: InterfaceCommunicator? = null

    override fun onAttach(context: Context?) {
        super.onAttach(context)
        listener = context as InterfaceCommunicator
    }

    interface InterfaceCommunicator {
        fun sendRequest(value: String)
    }   

    override fun onClick(v: View) {
        when (v.id) {
            R.id.buttonOk -> {    
        //You can change value             
                listener?.sendRequest('send data')
                dismiss()
            }
            
        }
    }
}

//我的活动

class MyActivity: AppCompatActivity(),FiltroDialogFragment.InterfaceCommunicator {

    override fun sendRequest(value: String) {
    // :)
    Toast.makeText(this, value, Toast.LENGTH_LONG).show()
    }
}
 

我希望它服务,如果你可以改进,请编辑它。 我的英语不太好