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

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

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

谢谢你的帮助。


当前回答

有一种更简单的方法来接收来自DialogFragment的结果。

首先,在你的Activity、Fragment或FragmentActivity中,你需要添加以下信息:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Stuff to do, dependent on requestCode and resultCode
    if(requestCode == 1) { // 1 is an arbitrary number, can be any int
         // This is the return result of your DialogFragment
         if(resultCode == 1) { // 1 is an arbitrary number, can be any int
              // Now do what you need to do after the dialog dismisses.
         }
     }
}

requestCode基本上是你调用的DialogFragment的int标签,我马上会展示它是如何工作的。resultCode是你从DialogFragment发送回来的代码,告诉你当前正在等待的Activity、Fragment或FragmentActivity发生了什么。

下一段代码是对DialogFragment的调用。这里有一个例子:

DialogFragment dialogFrag = new MyDialogFragment();
// This is the requestCode that you are sending.
dialogFrag.setTargetFragment(this, 1);     
// This is the tag, "dialog" being sent.
dialogFrag.show(getFragmentManager(), "dialog");

用这三行你声明了你的DialogFragment,设置了一个requestCode(它将调用onActivityResult(…)一旦对话框被驳回,然后你就会显示对话框。就是这么简单。

现在,在你的DialogFragment中,你只需要在dismiss()之前直接添加一行,这样你就可以将resultCode发送回onActivityResult()。

getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, getActivity().getIntent());
dismiss();

就是这样。注意,resultCode被定义为int resultCode,我已经设置为resultCode = 1;在这种情况下。

就是这样,你现在可以把你的DialogFragment的结果发送回你调用的Activity, Fragment,或者FragmentActivity。

另外,看起来这些信息之前已经发布了,但是没有给出足够的例子,所以我想我应该提供更多的细节。

编辑06.24.2016 我为上面的误导性代码道歉。但是你肯定不能接收回活动的结果,就像这行:

dialogFrag.setTargetFragment(this, 1);

设置目标片段而不是活动。为了做到这一点,你需要实现一个interfacecommunator。

在你的DialogFragment中设置一个全局变量

public InterfaceCommunicator interfaceCommunicator;

创建一个公共函数来处理它

public interface InterfaceCommunicator {
    void sendRequestCode(int code);
}

然后,当你准备好在DialogFragment完成运行时将代码发送回Activity时,你只需在你dismiss()之前添加一行;你的DialogFragment:

interfaceCommunicator.sendRequestCode(1); // the parameter is any int code you choose.

现在在你的活动中你必须做两件事,第一件事是删除那一行不再适用的代码:

dialogFrag.setTargetFragment(this, 1);  

然后实现接口,一切都完成了。你可以通过在类顶部的implements子句中添加以下一行来做到这一点:

public class MyClass Activity implements MyDialogFragment.InterfaceCommunicator

然后@Override activity中的函数,

@Override
public void sendRequestCode(int code) {
    // your code here
}

使用这个接口方法就像使用onActivityResult()方法一样。除了接口方法是针对DialogFragments,另一个是针对Fragments。

其他回答

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

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

好吧,现在回答可能为时已晚,但这是我从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();
    }

不同的方法,允许一个片段与它的活动通信:

1)在片段中定义一个公共接口,并为其创建一个变量

public OnFragmentInteractionListener mCallback;

public interface OnFragmentInteractionListener {
    void onFragmentInteraction(int id);
}

2)将活动转换为片段中的mCallback变量

try {
    mCallback = (OnFragmentInteractionListener) getActivity();
} catch (Exception e) {
    Log.d(TAG, e.getMessage());
}

3)在你的活动中实现监听器

public class MainActivity extends AppCompatActivity implements DFragment.OnFragmentInteractionListener  {
     //your code here
}

4)在活动中覆盖OnFragmentInteraction

@Override
public void onFragmentInteraction(int id) {
    Log.d(TAG, "received from fragment: " + id);
}

更多信息:https://developer.android.com/training/basics/fragments/communicating.html

有一种更简单的方法来接收来自DialogFragment的结果。

首先,在你的Activity、Fragment或FragmentActivity中,你需要添加以下信息:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Stuff to do, dependent on requestCode and resultCode
    if(requestCode == 1) { // 1 is an arbitrary number, can be any int
         // This is the return result of your DialogFragment
         if(resultCode == 1) { // 1 is an arbitrary number, can be any int
              // Now do what you need to do after the dialog dismisses.
         }
     }
}

requestCode基本上是你调用的DialogFragment的int标签,我马上会展示它是如何工作的。resultCode是你从DialogFragment发送回来的代码,告诉你当前正在等待的Activity、Fragment或FragmentActivity发生了什么。

下一段代码是对DialogFragment的调用。这里有一个例子:

DialogFragment dialogFrag = new MyDialogFragment();
// This is the requestCode that you are sending.
dialogFrag.setTargetFragment(this, 1);     
// This is the tag, "dialog" being sent.
dialogFrag.show(getFragmentManager(), "dialog");

用这三行你声明了你的DialogFragment,设置了一个requestCode(它将调用onActivityResult(…)一旦对话框被驳回,然后你就会显示对话框。就是这么简单。

现在,在你的DialogFragment中,你只需要在dismiss()之前直接添加一行,这样你就可以将resultCode发送回onActivityResult()。

getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, getActivity().getIntent());
dismiss();

就是这样。注意,resultCode被定义为int resultCode,我已经设置为resultCode = 1;在这种情况下。

就是这样,你现在可以把你的DialogFragment的结果发送回你调用的Activity, Fragment,或者FragmentActivity。

另外,看起来这些信息之前已经发布了,但是没有给出足够的例子,所以我想我应该提供更多的细节。

编辑06.24.2016 我为上面的误导性代码道歉。但是你肯定不能接收回活动的结果,就像这行:

dialogFrag.setTargetFragment(this, 1);

设置目标片段而不是活动。为了做到这一点,你需要实现一个interfacecommunator。

在你的DialogFragment中设置一个全局变量

public InterfaceCommunicator interfaceCommunicator;

创建一个公共函数来处理它

public interface InterfaceCommunicator {
    void sendRequestCode(int code);
}

然后,当你准备好在DialogFragment完成运行时将代码发送回Activity时,你只需在你dismiss()之前添加一行;你的DialogFragment:

interfaceCommunicator.sendRequestCode(1); // the parameter is any int code you choose.

现在在你的活动中你必须做两件事,第一件事是删除那一行不再适用的代码:

dialogFrag.setTargetFragment(this, 1);  

然后实现接口,一切都完成了。你可以通过在类顶部的implements子句中添加以下一行来做到这一点:

public class MyClass Activity implements MyDialogFragment.InterfaceCommunicator

然后@Override activity中的函数,

@Override
public void sendRequestCode(int code) {
    // your code here
}

使用这个接口方法就像使用onActivityResult()方法一样。除了接口方法是针对DialogFragments,另一个是针对Fragments。

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

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