Android 从DialogFragment接收结果

Android 从DialogFragment接收结果,android,dialog,android-fragments,fragment,dismiss,Android,Dialog,Android Fragments,Fragment,Dismiss,我使用DialogFragments进行了很多操作:从列表中选择项目,输入文本 将值(即字符串或列表中的项目)返回调用活动/片段的最佳方式是什么 目前,我正在使调用活动实现dismissleener,并为DialogFragment提供对该活动的引用。然后,对话框调用活动中的OnDimiss方法,活动从DialogFragment对象获取结果。由于DialogFragment丢失了对活动的引用,因此非常混乱,并且在配置更改(方向更改)上不起作用 感谢您的帮助。从显示对话框的位置使用myDialo

我使用DialogFragments进行了很多操作:从列表中选择项目,输入文本

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

目前,我正在使调用活动实现
dismissleener
,并为DialogFragment提供对该活动的引用。然后,对话框调用活动中的
OnDimiss
方法,活动从DialogFragment对象获取结果。由于DialogFragment丢失了对活动的引用,因此非常混乱,并且在配置更改(方向更改)上不起作用


感谢您的帮助。

从显示对话框的位置使用
myDialogFragment.setTargetFragment(这是我的请求代码)
,然后当对话框完成时,您可以从中调用
getTargetFragment().onActivityResult(getTargetRequestCode(),…)
,并实现
onActivityResult()
在包含的片段中

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

正如您所看到的,有一种非常简单的方法可以做到这一点

对话框fragment
中添加一个界面侦听器,如:

public interface EditNameDialogListener {
    void onFinishEditDialog(String inputText);
}
然后,添加对该侦听器的引用:

private EditNameDialogListener listener;
这将用于“激活”侦听器方法,并检查父活动/片段是否实现了此接口(请参见下文)

在名为“调用”的
对话框Fragment
活动中,只需实现此接口

对话框片段
中,您需要添加的所有内容都是在希望关闭
对话框片段
并返回结果的地方:

listener.onFinishEditDialog(mEditText.getText().toString());
this.dismiss();
其中
mEditText.getText().toString()
是将传递回调用的
活动的内容

请注意,如果要返回其他内容,只需更改侦听器的参数

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

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

这项技术非常灵活,即使您的don;我现在还不想关闭对话框。

有一种更简单的方法可以从DialogFragment接收结果

首先,在活动、片段或片段活动中,您需要添加以下信息:

@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返回的代码,告诉您当前正在等待的活动、片段或片段活动发生了什么

下一段代码是对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中,您只需在
dismise()
之前直接添加一行,以便将结果代码发送回onActivityResult()

就是这样。注意,resultCode定义为
int resultCode
,在本例中,我将其设置为
resultCode=1;

就这样,您现在可以将DialogFragment的结果发送回调用活动、Fragment或FragmentActivity

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

编辑2016年6月24日 我为上面的误导性代码道歉。但您肯定无法将结果返回到活动,因为行:

dialogFrag.setTargetFragment(this, 1);
设置目标
片段
而不是
活动
。因此,要实现此目的,您需要使用实现
接口通讯器

对话框fragment
中设置一个全局变量

public InterfaceCommunicator interfaceCommunicator;
创建一个公共函数来处理它

public interface InterfaceCommunicator {
    void sendRequestCode(int code);
}
然后,当您准备将代码发送回
活动时,当
对话框片段
运行完毕时,您只需在
dismise();
对话框片段
之前添加该行即可:

interfaceCommunicator.sendRequestCode(1); // the parameter is any int code you choose.
在您的活动中,现在您必须做两件事,第一件事是删除不再适用的一行代码:

dialogFrag.setTargetFragment(this, 1);  
然后实现接口,您就完成了。您可以通过将以下行添加到类顶部的
implements
子句来实现:

public class MyClass Activity implements MyDialogFragment.InterfaceCommunicator
然后,
@覆盖活动中的函数

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

您使用此接口方法就像使用onActivityResult()一样
方法。除了接口方法是用于
对话片段
和另一种是用于
片段

之外,我非常惊讶地看到,没有人建议使用本地广播进行
对话片段
活动
交流!我发现它比其他建议更简单、更干净。Es值得注意的是,您注册了
活动
来收听广播,然后从
对话框片段
实例发送本地广播。简单。有关如何设置所有内容的分步指南,请参阅。

我发现的一个简单方法是: 这是你的对话片段

  CallingActivity callingActivity = (CallingActivity) getActivity();
  callingActivity.onUserSelectValue("insert selected value here");
  dismiss();
然后在调用对话框片段的活动中创建相应的函数:

 public void onUserSelectValue(String selectedValue) {

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

祝酒词是为了证明它是有效的。对我来说是有效的。

回答这个问题可能太晚了,但下面是我从
对话框片段
中得到的结果。与@brandon的回答非常相似。 我是calli
 public void onUserSelectValue(String selectedValue) {

        // TODO add your implementation.
      Toast.makeText(getBaseContext(), ""+ selectedValue, Toast.LENGTH_LONG).show();
    }
FragmentManager fragmentManager = getFragmentManager();
            categoryDialog.setTargetFragment(this,1);
            categoryDialog.show(fragmentManager, "dialog");
            Intent intent = new Intent();
            intent.putExtra("listdata", stringData);
            getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);
            getDialog().dismiss();
 @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();
    }
 ((Interface)getTargetFragment()).onSomething(selectedListPosition);
public OnFragmentInteractionListener mCallback;

public interface OnFragmentInteractionListener {
    void onFragmentInteraction(int id);
}
try {
    mCallback = (OnFragmentInteractionListener) getActivity();
} catch (Exception e) {
    Log.d(TAG, e.getMessage());
}
public class MainActivity extends AppCompatActivity implements DFragment.OnFragmentInteractionListener  {
     //your code here
}
@Override
public void onFragmentInteraction(int id) {
    Log.d(TAG, "received from fragment: " + id);
}
bus.post(new AnswerAvailableEvent(42));
@Subscribe public void answerAvailable(AnswerAvailableEvent event) {
   // TODO: React to the event somehow!
}
    // 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()
    }
}
 
public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }

    public LiveData<Item> getSelected() {
        return selected;
    }
}


public class MasterFragment extends Fragment {
    private SharedViewModel model;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends Fragment {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        model.getSelected().observe(this, { item ->
           // Update the UI.
        });
    }
}
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");
}
class AbcDialogFragment(private val ondata: (data: String) -> Unit) :  DialogFragment() {}
val abcDialogFragment = AbcDialogFragment(ondata = {data->  })
                
abcDialogFragment.show(requireActivity().supportFragmentManager, "TAG")