Я не уверен, что это был бы правильный путь. У меня есть несколько призывов к действию для результата в разных фрагментах. Должен ли каждый фрагмент иметь свой onActivityResult? Или все это должно быть обработано в onActivityResult активности?
Если я запускаю действие для результата из фрагмента, должен ли я вызывать результат действия во фрагменте или действии?
Ответы (3)
Вы должны реализовать onActityResult
для каждого Fragment
, который запустил действие через startActivityForResult
. Таким образом, каждый фрагмент может правильно отслеживать результат: результат действия имеет смысл только для того фрагмента, который его запросил.
На то тоже есть причина.
Когда вы начинаете действие, вы должны установить requestCode:
// Note the request code: 0
startActivityForResult(0, new Intent(...))
Однако, если вы вызываете этот метод из Fragment
, Android внутренне изменит код запроса (чтобы он мог автоматически отслеживать фрагмент, вызвавший запрос). Это происходит потому, что хозяин Fragment
является FragmentActivity
, а не простым 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);
}
Таким образом, когда onActivityResult
срабатывает, вы можете зафиксировать результат активности хоста. Однако в действии хоста requestCode больше не тот, который вы отправили, а requestCode изменен Android внутри:
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);
}
Как видите, вы можете зафиксировать результат действия в действии хоста. Однако код запроса не длиннее установленного вами (0). Итак, здесь вы не можете отследить код запроса. Таким образом, вы не можете отследить, от кого этот результат.
Android вызовет onActivityResult
в вашем фрагменте. Однако перед вызовом фрагмента код запроса преобразуется обратно в отправленное вами значение (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);
}
Итак, есть еще причина реализовать onActivityResult
в вашем фрагменте. Особенно, если у вас есть разные фрагменты, запускающие разные действия и т. д. Если вы всегда запускаете одно и то же действие, вы можете ошибочно предположить, что можете реализовать onActityResult
где угодно. Однако это не так. Каждый фрагмент или действие должны обрабатывать запрошенный результат действия. Они не должны обрабатывать результат других сущностей. Вы можете сделать это, но это только усложнит ваш код.
Когда вы запускаете действие для результата из фрагмента, просто не забудьте не использовать getActivity().startActivityForResult(), используйте только startActivityForResult и переопределите onActivityResult во фрагменте, и вы получите обратный вызов.
Вот три ситуации
Запуск активности из вложенного фрагмента
Что за вложенный фрагмент?
A fragment embed into another fragment
Почему вложенный фрагмент не может получить обратный вызов
onActivityResult()
?Проверьте эту ссылку.
Как вручную вызвать
onActivityResult()
для вложенного фрагментаПроверьте эту ссылку.