На базе этого материала, а когда надоело — поста Android Live.
С момента выхода компонентов Android Architecture разработка под Android становиться легче и эффективнее. С другой стороны и устоявшиеся концепты претерпели немало изменений (единичная activity, к примеру).
Для реализации подобных идей разработчики всё чаще переходят от традиционных активностей к более эффективным фрагментам. Но тут есть затруднительная ситуация для них, которая связана с передачей данных между фрагментами.
Проблема старого решения
Передача данных между фрагментами без использования каких-либо ссылок (context, интерфейсы, общие viewmodel или live data на уровне приложения) выглядит практически невозможным. Но если копнуть глубже, то вы найдете решение: targetFragment.
targetFragment предоставляет возможность связаться с фрагментом в back stack. Никакие ссылки на место назначения в источнике не нужны. Иными словами, targetFragment это способ реализовать функционал onActivityResult, но во фрагменте.
Несмотря на кажующуюся простоту, это API — не очень удобное.
Во-первых, targetFragment будет работать если фрагменты находятся в одном и том же менеджере.
Во-вторых, API разбросано по коду и становится непонятно, откуда прилетел тот или иной кусок данных.
Новое решение
Не так давно появилось новое решение — FragmentResultOwner. По сути, это callback, который есть у каждого FragmentManager.
Это изменение позволяет отдельным фрагментам взаимодействовать друг с другом, отправляя результаты фрагмента и прослушивая эти результаты, не требуя, чтобы фрагменты имели прямые ссылки друг на друга.
Работает он примерно так:
1 2 3 4 |
setFragmentResultListener("requestKey") { key, bundle -> val result = bundle.getString("name") // Do something with the result… } |
А в том месте, где мы хотим отправить информацию нужно вызвать:
1 2 3 |
tvSave.setOnClickListener { setResult("requestKey", bundleOf("name" to updatedValue)) } |
Точно такого же слушателя мы можем добавить и для childfragmentmanager.
В целом, новое API выглядит гораздо интереснее предыдущего и виден явный прогресс.