Стратегия переноса

Если у вас уже есть приложение на основе View, вы можете не захотеть переписывать весь его интерфейс сразу. На этой странице рассказывается, как добавить новые компоненты Compose в существующее приложение. Чтобы начать использовать Compose в приложении, ознакомьтесь со статьей Как настроить Compose для существующего приложения.

Jetpack Compose изначально разрабатывался с учетом совместимости с View. Это значит, что вы можете перенести существующее приложение на основе View в Compose и при этом создавать новые функции. Мы рекомендуем переходить на Compose постепенно, чтобы в коде приложения одновременно использовались и Compose, и View.

Этапы переноса приложения на основе View в Compose
Рисунок 1. Этапы переноса приложения на основе View в Compose

Чтобы перенести приложение на Compose, выполните следующие действия:

  1. Создавать новые экраны с помощью Compose.
  2. При разработке функций выявляйте элементы, которые можно использовать повторно, и создавайте библиотеку общих компонентов интерфейса.
  3. Заменяйте существующие функции по одной.

Как создавать новые экраны с помощью Compose

Лучший способ начать использовать Compose – создавать с его помощью новые функции, занимающие весь экран. Эта стратегия позволяет добавлять функции и использовать преимущества Compose, не нарушая бизнес-процессы компании.

Новый экран, созданный с помощью Compose
Рисунок 2. Новый экран, написанный на языке Compose

При создании новых экранов в существующем приложении с помощью Compose вы по-прежнему работаете в рамках архитектуры приложения. Если вы используете фрагменты и компонент Navigation, вам нужно создать новый фрагмент и разместить его содержимое в Compose.

Чтобы использовать Compose во фрагменте, верните ComposeView в методе жизненного цикла onCreateView() фрагмента. В ComposeView есть метод setContent(), в котором можно указать composable-функцию.

class NewFeatureFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return ComposeView(requireContext()).apply {
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                NewFeatureScreen()
            }
        }
    }
}

Подробнее о ComposeView во фрагментах…

Добавлять новые функции на существующие экраны.

Существующий экран с элементами View и Compose
Рисунок 3. Существующий экран со смешанным использованием Views и Compose

Вы также можете использовать Compose на существующем экране на основе View, если добавляемая функция является частью этого экрана. Для этого добавьте ComposeView в иерархию View так же, как и любое другое представление.

Например, вы хотите добавить дочернее представление в LinearLayout. В XML это можно сделать следующим образом:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <TextView
      android:id="@+id/text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" />

  <androidx.compose.ui.platform.ComposeView
      android:id="@+id/compose_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />
</LinearLayout>

После того как представление будет развернуто, вы сможете ссылаться на ComposeView в иерархии и вызывать setContent().

Чтобы узнать больше о ComposeView, ознакомьтесь с API для взаимодействия.

Создайте библиотеку стандартных компонентов интерфейса

При создании функций с помощью Compose вы быстро поймете, что в итоге у вас получается библиотека компонентов. Создание библиотеки общих компонентов интерфейса позволяет иметь единый источник достоверных данных для этих компонентов в приложении и способствует их повторному использованию. Функции, которые вы создаете, могут зависеть от этой библиотеки. Этот метод особенно полезен, если вы создаете собственную систему дизайна в Compose.

В зависимости от размера приложения эта библиотека может быть отдельным пакетом, модулем или библиотечным модулем. Подробнее о том, как организовать модули в приложении, можно узнать из руководства по модульности приложений Android.

Замена существующих функций на Compose

Помимо создания новых функций с помощью Compose, вы можете постепенно переносить на него существующие функции приложения.

Использование только Compose может ускорить разработку, а также уменьшить размер APK-файла и время сборки приложения. Подробнее о сравнении производительности Compose и View…

Простые экраны

При переносе существующих функций в Compose в первую очередь следует обратить внимание на простые экраны. Простыми экранами могут быть экран приветствия, экран подтверждения или экран настроек, на котором данные в интерфейсе относительно статичны.

Возьмем следующий XML-файл:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <TextView
      android:id="@+id/title_text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@string/title"
      android:textAppearance="?attr/textAppearanceHeadline2" />

  <TextView
      android:id="@+id/subtitle_text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@string/subtitle"
      android:textAppearance="?attr/textAppearanceHeadline6" />

  <TextView
      android:id="@+id/body_text"
      android:layout_width="wrap_content"
      android:layout_height="0dp"
      android:layout_weight="1"
      android:text="@string/body"
      android:textAppearance="?attr/textAppearanceBody1" />

  <Button
      android:id="@+id/confirm_button"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="@string/confirm"/>
</LinearLayout>

XML-файл можно переписать на Compose в несколько строк:

@Composable
fun SimpleScreen() {
    Column(Modifier.fillMaxSize()) {
        Text(
            text = stringResource(R.string.title),
            style = MaterialTheme.typography.headlineMedium
        )
        Text(
            text = stringResource(R.string.subtitle),
            style = MaterialTheme.typography.headlineSmall
        )
        Text(
            text = stringResource(R.string.body),
            style = MaterialTheme.typography.bodyMedium
        )
        Spacer(modifier = Modifier.weight(1f))
        Button(onClick = { /* Handle click */ }, Modifier.fillMaxWidth()) {
            Text(text = stringResource(R.string.confirm))
        }
    }
}

Комбинированный просмотр и экраны Compose

Экран, в котором уже есть код Compose, – ещё один хороший кандидат для полного перехода на Compose. В зависимости от сложности экрана вы можете перенести его в Compose целиком или по частям. Если экран был создан с помощью Compose в поддереве иерархии интерфейса, вы продолжите переносить элементы интерфейса, пока весь экран не будет создан с помощью Compose. Этот подход также называют снизу вверх.

Переход с интерфейса на основе представлений и Compose на Compose с использованием подхода &quot;снизу вверх&quot;
Рисунок 4. Переход с интерфейса на основе представлений и Compose на Compose с использованием подхода "снизу вверх"

Удаление фрагментов и компонента навигации

Вы можете перейти на Navigation Compose, когда сможете удалить все фрагменты и заменить их на соответствующие компонуемые функции на уровне экрана. Компоненты на уровне экрана могут содержать контент Compose и View, но все пункты назначения навигации должны быть компонентами, чтобы можно было перейти на Navigation Compose. До этого времени в коде, содержащем как компоненты View, так и Compose, следует использовать компонент навигации на основе фрагментов. Подробнее о том, как перейти с Jetpack Navigation на Navigation Compose…

Дополнительные ресурсы

Чтобы узнать больше о переносе приложения на основе View в Compose, ознакомьтесь со следующими ресурсами:

Дальнейшие действия

Теперь, когда вы знаете, как перенести существующее приложение на основе View, изучите API совместимости.