Предположим, вас занесло в чудный мир программистов для Андроид. Вы прониклись туториалами и описаниями об Активностях и Фрагментах. Начали красиво писать первые скромные поделки… Хорошо? Благодать? Уже расслабились и получаете удовольствие? А вот тут раз и из-за угла вам лопатой!
Дело было так. Вы написали Активность, а в неё чудесно вписали красивый Фрагментик. Но вы же захотели большего — вызвать из этого Фрагментика на экран другую Активность! Эка наглость… Не просто вызвать, а вызвать для результата. То есть, она для вас должна вернуть полезные данные.
Кусок текста Фрагмента:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class LittleFragment: Fragment() {
…
// На нажатие волшебной кнопки
fun onClick() {
// Формируем запрос и отправляем его, ожидая в ответ полезные данные
val intent = …
startActivityForResult(intent, REQUEST_DATA)
}
…
// Ловушка для полезных данных
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
Log.d(TAG, "onActivityResult(requestCode = $requestCode, resultCode = $resultCode)")
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_DATA ->
updateSomething()
else ->
Log.e(TAG, "onActivityResult: wrong request code!")
}
}
}
…
} |
Начинаете эксперименты… Продолжаете эксперименты… Продолжаете… Но ловушка просто так работать отказывается. После недолгих скитаний от кофемашины до компуктера, от балкона до кота, становится ясно, что ответ получает ловушка, расположенная у родительской Активности! Вот ведь… Чего ж нас раньше в детском садике не предупредили? Тупо копируем нашу ловушку в Активность — в ответ граблями по наглой морде:
Родительская активность получает ответ немного другой формы. Хуже того, у родительской Активности могут быть свои котлеты и перемешивать их с кодами запросов нашего фрагмента — как-то не по-джентельменски. Возвращаем ловушку обратно, а у родительской Активности пишем закленания:
Код родительской Активности:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class MainActivity : AppCompatActivity() {
…
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
Log.d(TAG, "onActivityResult(requestCode = $requestCode, resultCode = $resultCode)")
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_DATA1_FOR_MAIN_ACTIVITY -> {
// …
}
REQUEST_DATA2_FOR_MAIN_ACTIVITY -> {
// …
}
else -> {
// Если ожидаемые коды не подходят — пытаемся определить дочерний Фрагмент,
// инициировавший происходящие события. requestCode в старших разрядах содержит индекс:
val fragmentIndex = requestCode.shr(16)
if (fragmentIndex>0) {
// Надо передать дочернему фрагменту
val fragments = supportFragmentManager.fragments
if (fragmentIndex>fragments.size)
Log.e(TAG, "onActivityResult: wrong request code!")
else {
Log.i(TAG, "onActivityResult: transfer result to fragment.")
fragments[fragmentIndex-1].onActivityResult(
requestCode.and(0xFFFF),
resultCode, data)
}
}
}
}
}
super.onActivityResult(requestCode, resultCode, data)
} |
Такому в Хогвардсе не учат. Это жизнь, детка!