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

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

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

谢谢你的帮助。


当前回答

关于一个对话片段

class AbcDialogFragment(private val ondata: (data: String) -> Unit) :  DialogFragment() {}

显示片段/活动对话框的代码

val abcDialogFragment = AbcDialogFragment(ondata = {data->  })
                
abcDialogFragment.show(requireActivity().supportFragmentManager, "TAG")

在对话片段中,你可以在对话片段关闭或任何点击监听器时调用onData。

其他回答

使用myDialogFragment。setTargetFragment(this, MY_REQUEST_CODE)从你显示对话框的地方,然后当你的对话框完成时,从它可以调用getTargetFragment().onActivityResult(getTargetRequestCode(),…),并在包含的片段中实现onActivityResult()。

这似乎是对onActivityResult()的滥用,特别是因为它根本不涉及活动。但我看到官方谷歌的人推荐它,甚至可能在api演示中。我认为这是g/setTargetFragment()被添加的原因。

我发现了一个简单的方法: 实现这个是你的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();
    }

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

如果你想发送参数并从第二个片段接收结果,你可以使用fragment。setargarguments来完成这个任务

static class FirstFragment extends Fragment {
    final Handler mUIHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 101: // receive the result from SecondFragment
                Object result = msg.obj;
                // do something according to the result
                break;
            }
        };
    };

    void onStartSecondFragments() {
        Message msg = Message.obtain(mUIHandler, 101, 102, 103, new Object()); // replace Object with a Parcelable if you want to across Save/Restore
                                                                               // instance
        putParcelable(new SecondFragment(), msg).show(getFragmentManager().beginTransaction(), null);
    }
}

static class SecondFragment extends DialogFragment {
    Message mMsg; // arguments from the caller/FirstFragment

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onViewCreated(view, savedInstanceState);
        mMsg = getParcelable(this);
    }

    void onClickOK() {
        mMsg.obj = new Object(); // send the result to the caller/FirstFragment
        mMsg.sendToTarget();
    }
}

static <T extends Fragment> T putParcelable(T f, Parcelable arg) {
    if (f.getArguments() == null) {
        f.setArguments(new Bundle());
    }
    f.getArguments().putParcelable("extra_args", arg);
    return f;
}
static <T extends Parcelable> T getParcelable(Fragment f) {
    return f.getArguments().getParcelable("extra_args");
}

在我的例子中,我需要将参数传递给一个targetFragment。但我发现异常"碎片已激活"所以我在我的DialogFragment中声明了一个接口,这是parentFragment实现的。当parentFragment启动一个DialogFragment时,它将自己设置为TargetFragment。然后在DialogFragment中调用

 ((Interface)getTargetFragment()).onSomething(selectedListPosition);

对于还在阅读这篇文章的人: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()
}