从DialogFragment接收结果

我正在使用DialogFragments的许多事情:从列表中select项目,input文本。

什么是最好的方式返回一个值(即从列表中的string或项目)回到调用活动/片段?

目前,我正在使调用活动实现DismissListener并给DialogFragment一个参考活动。 然后Dialog调用活动中的OnDimiss方法,活动从DialogFragment对象中获取结果。 非常混乱,而且在DialogFragment失去对活动的引用时,它不能在configuration更改(方向更改)上工作。

谢谢你的帮助。

从显示对话框的位置使用myDialogFragment.setTargetFragment(this, MY_REQUEST_CODE) ,然后当对话结束时,可以调用getTargetFragment().onActivityResult(getTargetRequestCode(), ...) ,并实现onActivityResult()在包含片段中。

这似乎是onActivityResult()的滥用,尤其是因为它根本不涉及任何活动。 但是我已经看到官方的谷歌推荐,甚至可能在API的演示。 我想这是什么g/setTargetFragment()被添加。

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

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

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

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

 private EditNameDialogListener listener; 

这将用于“激活”侦听器方法,还用于检查父Activity / Fragment是否实现了此接口(请参见下文)。

在“调用” DialogFragmentActivity / FragmentActivity / Fragment中简单地实现这个接口。

在你的DialogFragment你需要添加一个你想closuresDialogFragment并返回结果是这样的:

 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接收结果有一个更简单的方法。

首先,在您的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(一旦Dialogclosures就调用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); 

设置一个目标Fragment而不是Activity 。 所以为了做到这一点,你需要使用一个InterfaceCommunicator实现。

在你的DialogFragment设置一个全局variables

 public InterfaceCommunicator interfaceCommunicator; 

创build一个公共的函数来处理它

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

然后,当您准备好在DialogFragment运行DialogFragment代码发送回Activity时,您只需在dismiss();之前添加该行即可dismiss(); 你的DialogFragment

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

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

 dialogFrag.setTargetFragment(this, 1); 

然后实现界面,你都完成了。 您可以通过将以下行添加到类的最顶部的implements子句中来implements

 public class MyClass Activity implements MyDialogFragment.InterfaceCommunicator 

然后@Override活动中的function,

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

您可以像使用onActivityResult()方法一样使用此接口方法。 除了接口方法是用于DialogFragments ,另一个用于Fragments

那么为时已晚,可能会回答,但这是我从DialogFragment得到的结果。 非常类似@布兰登的答案。 在这里,我从一个片段调用DialogFragment ,只需将这个代码放在你调用对话框的地方。

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

其中categoryDialog是我想要调用的DialogFragment ,然后在实现dialogfragment ,将此代码放置在您正在设置数据的位置。 resultCode的值是1,您可以设置它或使用系统Defined。

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

现在是回到调用片段并实现这个方法的时候了。 检查数据有效性或结果是否成功,如果你想resultCoderequestCode在if条件。

  @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(); } 

我很惊讶地看到,没有人build议使用本地广播进行DialogFragmentActivity通信! 我发现它比其他build议更简单,更清洁。 基本上,你注册你的Activity来监听广播,并从DialogFragment实例发送本地广播。 简单。 有关如何完成设置的分步指南,请参阅此处 。

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

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

然后在调用Dialog Fragment的活动中创build相应的function:

  public void onUserSelectValue(String selectedValue) { // TODO add your implementation. Toast.makeText(getBaseContext(), ""+ selectedValue, Toast.LENGTH_LONG).show(); } 

敬酒是要表明它的工作。 为我工作。

不同的方法,以允许一个片段沟通到其活动

1)在片段中定义一个公共接口并为其创build一个variables

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

2)将活动投射到片段中的mCallbackvariables

 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

在我的情况下,我需要传递参数到一个targetFragment。 但是我得到了“片段已经激活”的例外。 所以我在DialogFragment中声明了一个实现了parentFragment的接口。 当parentFragment启动一个DialogFragment时,它将自己设置为TargetFragment。 然后在DialogFragment中调用

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

只是把它作为选项之一(因为没有人提到它) – 你可以使用像奥托这样的事件公共汽车。 所以在对话框中你可以:

 bus.post(new AnswerAvailableEvent(42)); 

并让你的调用者(Activity或Fragment)订阅它:

 @Subscribe public void answerAvailable(AnswerAvailableEvent event) { // TODO: React to the event somehow! }