С момента выхода Jetpack Compose в 2021 году многие разработчики Android перевели свои приложения на этот новый UI-фреймворк. Однако одной из самых больших проблем является перенос системы навигации со старой, основанной на Фрагментах, на новую, основанную на Compose.
Основной план перехода с Fragments на Compose заключался в следующем:
- Использовать Compose в качестве пользовательского интерфейса внутри Фрагментов.
- Сделать всю инфраструктуру, созданную в Fragments, в Compose (Analytics и т. д.)
- Заменить навигацию, основанную на Фрагментах, на навигацию, основанную на Compose.
Для небольших проектов это легко сделать за несколько дней, но для крупных компаний это огромная задача, которая, вероятно, не сделать и в течение многих лет!
Поэтому вместо того, чтобы переносить все фрагменты один за другим, есть ли способ просто использовать Фрагменты внутри Compose?
AndroidViewBinding
Это действительно возможно с помощью AndroidViewBinding
, но только если наш фрагмент не имеет аргументов, потому что он использует преимущества FragmentContainerView
, в котором имя класса фрагмента объявляется в XML и инстанцируется для нас под капотом:
@Composable fun DashboardScreen() { val context = LocalContext.current val binding = FragmentDashboardBinding.inflate(LayoutInflater.from(context)) AndroidViewBinding(FragmentDashboardBinding::inflate) { // Do something on the binding if necessary } }
Макет dashboard_fragment.xml
выглядит следующим образом:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <androidx.fragment.app.FragmentContainerView android:id="@+id/fragmentContainer" android:name="dev.galex.compose.app.DashboardFragment" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
AndroidFragment
AndroidFragment
— это новый @Composable, который позволяет нам использовать фрагменты непосредственно в Compose.
Внутри нашего собственного @Composable мы можем использовать AndroidFragment
следующим образом:
@Composable fun ItemScreen( modifier: Modifier = Modifier, itemId: String, ) { AndroidFragment<ItemFragment>( arguments = bundleOf(ItemFragment.ARG_ID to "some-id"), modifier = modifier.fillMaxSize() ) }
AndroidFragment
доступен в библиотеке androidx.fragment:fragment-compose с версии 1.8.0-alpha01. Нужно добавить следующее в libs.version.toml
:
[versions] fragment = "1.8.0-alpha02" [libraries] androidx-fragment-compose = { group = "androidx.fragment", name = "fragment-compose", version.ref = "fragment" }
И добавить эту зависимость в наш модуль приложения build.gradle.kts
:
dependencies { implementation(libs.androidx.fragment.compose) }
⚠️ Это все еще альфа, поэтому я бы подождал, пока версия 1.8.0 станет стабильной, прежде чем использовать ее в проде.
Документация доступна здесь.
Заключение
Я очень рад появлению AndroidFragment, потому что нам больше не надо переписывать всех фрагменты в композабл, прежде чем мы сможем перейти на навигацию на основе Compose. Это позволит нам переходить на Compose постепенно, что является огромным преимуществом!