问题
I am not sure what would be the correct way. I have a few calls for action for result in different fragments. Should each fragment have its own onActivityResult? Or should it all be handles in the activity's onActivityResult?
回答1:
You must implement the onActityResult
for every Fragment
which started an activity via startActivityForResult
.
So, each fragment can track the result properly: The activity result makes sense only for the fragment which requested it.
There's also a reason for it.
When you start an activity, you have to set a requestCode:
// Note the request code: 0
startActivityForResult(0, new Intent(...))
However, if you call that method from inside a Fragment
, Android will internally change the request code (so it can automatically track the fragment which triggered the request).
This happens because the host of a Fragment
is a FragmentActivity
and not a simple Activity
// From FragmentActivity
// Note how the request Code is overriden ((requestIndex + 1) << 16) + (requestCode & 0xffff)
startActivityFromFragment(...) {
startActivityForResult(this, intent, ((requestIndex + 1) << 16) + (requestCode & 0xffff), options);
}
So, when the onActivityResult
is triggered, you can capture the result on the host activity. However, in the host activity, the requestCode is no longer the one that you sent but requestCode changed by Android internally:
In host activity:
@Override
protected void onActivityResult(final int requestCode, final int resultCode,
@Nullable final Intent data) {
// This print 65536
Log.v("TEST", "onActivityResult: " + requestCode);
super.onActivityResult(requestCode, resultCode, data);
}
As you can see, you can capture the activity result on the Host activity. However, the request code is not longer that one you set (0). So, here, you can't track the request code. So, you can't track from who this result is from.
Android will invoke onActivityResult
in your fragment. However, before invoking the fragment, the request code is converted back to the value that you sent (0):
// From FragmentActivity
// Note how the request Code is converted back to 0
onActivityResult(....) {
// Android will call your fragment with the correct requestCode
targetFragment.onActivityResult(requestCode & 0xffff, resultCode, data);
}
//In your fragment:
@Override
protected void onActivityResult(final int requestCode, final int resultCode,
@Nullable final Intent data) {
// This print 0. So, now, you know this is the result of the request 0
Log.v("TEST", "onActivityResult: " + requestCode);
}
So, there's also a reason to implement the onActivityResult
in your fragment. Specially if you have different fragments starting different activities etc. If you always start same activity, you may wrongly assume you can implement the onActityResult
wherever you want. However, that is not true.
Every fragment or activity should handle the activity result they requested. They should not handle the result of other entitities. You can do that but it will only add unnecessary complexity to your code.
回答2:
When you start activity for result from a fragment just do remember not to use getActivity().startActivityForResult(), Only use startActivityForResult and override the onActivityResult in the fragment and bam you’ll get the callback.
回答3:
Here are three situation
Start a activity from a fragment without using activity context
- Start a activity from a activity
Start a activity from a nested fragment
What a nested fragment?
A fragment embed into another fragment
Why nested fragment can not receive
onActivityResult()
callback?Check this link
How to manually invoke
onActivityResult()
to nested fragmentCheck this link
来源:https://stackoverflow.com/questions/56169383/if-i-start-activity-for-result-from-a-fragment-should-i-call-on-activity-result