在Fragment中的onActivityResult函数

35

我目前有一个基础活动,它托管了一个单一的片段。在片段内,我有一个启动联系人选择器的方法。

private void chooseContacts() {
    Intent pickContactIntent = new Intent(Intent.ACTION_PICK,      ContactsContract.Contacts.CONTENT_URI);
    pickContactIntent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
    startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}
当这个活动返回时,我应该如何捕获结果。我尝试添加了一个

标签。
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //Handle Code
}

对我的基础Activity和Fragment,我都尝试了,但两种方法都没有触发。如果可能的话,我想让Fragment处理返回,以免混淆Activity。

请告诉我在这种情况下最佳实践是什么。

更新:

如果我更改:

startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);

getActivity().startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);

那么它可以正常工作,但其他的帖子让我觉得这是不正确的。


还要确保您的hostActivity启动模式未设置为singleTask或singleInstance https://dev59.com/Cm025IYBdhLWcg3wNTEV#38760091 - Zar E Ahmer
4个回答

55

我认为在Fragment中直接使用startActivityForResult()调用,而不是使用getActivity().startActivityForResult()调用。

我在Fragment中调用了startActivityForResult(),并在Fragment中实现了onActivityResult方法,onActivityResult()被正确地调用了。

你不能在Activity中调用startActivityForResult(),否则Fragment中的onActivityResult()将不会被调用。


5

在我的情况下,我是在父活动中完成了这个操作。

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    for (Fragment fragment : getSupportFragmentManager().getFragments()) {
        fragment.onActivityResult(requestCode, resultCode, data);
    }
}

getSupportFragmentManager().getFragments() 不是公开方法,可用于应用程序。请查看文档:https://developer.android.com/reference/android/support/v4/app/FragmentManager.html - Pramod Garg
1
你可以直接在片段中调用startActivityForResult并在片段内实现onActivityResult。它会被调用。如果你还需要覆盖父活动中的onActivityResult,你只需要确保调用super.onActivityResult以确保你的片段的onActivityResult也被调用。你当前的解决方案基于不应该由开发人员代码调用的方法,并且基本上是在重新做支持库已经为你做的事情。 - Simon Ninon

1

片段的onActivityCreated有另一个用途:

当片段的活动已创建并实例化此片段的视图层次结构时调用。一旦这些部分就位,它可以用于进行最终初始化,例如检索视图或恢复状态。对于使用setRetainInstance(boolean)保留其实例的片段也很有用,因为此回调告诉片段它何时完全与新活动实例相关联。这在onCreateView(LayoutInflater, ViewGroup, Bundle)之后和onViewStateRestored(Bundle)之前调用。

这是从文档中提取的

主要使用片段,您将在onCreateView中填充并返回视图,在onViewCreated中执行视图操作(例如在ListView中设置ListAdapter)。在onActivityCreated中执行初始化操作(例如显示欢迎对话框或类似内容)。

您有几个选择,我不确定哪个更适合您的问题:

  • 在活动的onActivityResult中,我会执行findFragmentById方法,如果找到的fragment不为null,则调用处理来自联系人列表返回的方法。

  • 另一种方法是在活动的onActivityResult中触发一个BroadCastReceiver,并注册你的Fragment来监听该广播。但我认为对于这么简单的事情,这种方法太过繁琐。

  • 最后,像第一种方法一样,如果你没有带有id的Fragment,你可以在活动中实例化Fragment,保存一个引用,并在活动的onActivityResult被执行时发送一条消息给它。

希望其中的某些内容能帮助到你。


我尝试实现您的第一个解决方案,问题是主活动中的onActivityResult没有被调用。有什么想法吗? - Nath5
我通过以下方式使其工作: getActivity().startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST); 但是我已经阅读到这不是正确的方法。 - Nath5

1

这将帮助你在Fragment中使用onActivityResult

PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
startActivityForResult(builder.build(getActivity()), PLACE_PICKER_REQUEST);

public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == PLACE_PICKER_REQUEST) {
            if (resultCode == Activity.RESULT_OK) {
                Place place = PlacePicker.getPlace(data, getActivity());
             }
         }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接