Статьи

Android Jetpack Compose — раз и навсегда!

Jetpack compose для предварительного просмотра разработчиков, как было объявлено в Android Dev Summit 2019. Он вызывает шум в городе с его декларативными возможностями пользовательского интерфейса.

Недавно я попробовал Jetpack Compose, и он мне действительно понравился! Позвольте мне предвосхитить это, сказав, что мне на самом деле не очень понравился Флаттер. Несмотря на то, что он обладает всеми возможностями управления состоянием, декларативным пользовательским интерфейсом, но с DART он все еще кажется примитивным.

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

Что такое Jetpack Compose?

Jetpack Compose — это библиотека в Android Jetpack, которая позволяет разработчикам создавать составные функции. Представьте, что составные функции — это обычные функции Kotlin, возвращающие представление

Эта функция при вызове добавляет вид к вашему макету. Они снабжены аннотацией @Composable . Давайте посмотрим на пример функции ниже

1
2
3
4
5
6
7
@Composable
fun Greeting(name: String) {
    Text(
            text = "Hello $name!",
            modifier = Spacing(24.dp)
    )
}

Мы также можем иметь несколько вложенных представлений, таких как ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
@Composable
fun Content(counterState: State = State()) {
    Column(modifier = ExpandedHeight, crossAxisAlignment = CrossAxisAlignment.Center) {
        Column(modifier = Flexible(1f), crossAxisAlignment = CrossAxisAlignment.Center, mainAxisAlignment = MainAxisAlignment.Center) {
 
        }
 
        Row(modifier = ExpandedWidth, mainAxisAlignment = MainAxisAlignment.End) {
             
        }
 
    }
}

Если вы работали с Flutter , это может показаться вам очень похожим. И это! Jetpack Compose ощущается как флаттер на нативных стероидах …

Некоторые из лучших особенностей Jetpack Compose:

  • Создание декларативных интерфейсов.
  • Добавлена ​​поддержка в Android Studio 4 для мгновенного предварительного просмотра макетов.
  • Представления могут быть разбиты на функции и могут использоваться в нескольких местах.
  • Управление состоянием с помощью классов данных @Model действительно мощное. Мы рассмотрим это подробнее в следующих разделах.

Но это не все солнце и радуга. У меня есть некоторые проблемы с композитом, такие как:

  • Пользовательский интерфейс и логика связаны друг с другом. Я чувствую, поскольку Jetpack Compose переместит пользовательский интерфейс в файлы kotlin, это может привести к соединению кода.
  • Вложение: у меня была эта проблема с флаттером, и она не улучшается даже в Compose. Может быть, это только я, но идея нескольких вложенных фигурных скобок меня просто пугает.

Тем не менее, это здесь, и это рекомендуется Google. Итак, давайте посмотрим, каково это — создать простое приложение вроде «Hello World» с использованием Jetpack Compose в Android. Вот как это будет выглядеть:

Android Studio 4.0 Предварительный просмотр

Вы не сможете использовать Compose в текущей версии Android Studio. Для этого вам нужно установить AS 4.0 из канарского канала.

01
02
03
04
05
06
07
08
09
10
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApp {
                Content()
            }
        }
    }
}

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

  1. Перейдите в Настройки (Win) / Настройки (Mac).
  2. Затем перейдите в настройки системы -> Обновления
  3. Оттуда вы можете изменить свой стабильный канал на канарский канал.

Затем проверьте наличие обновлений. Он попросит вас загрузить AS 4.0 Preview. Итак, скачайте и установите его. Теперь мы будем создавать новый проект для сочинения.

Перейдите в File -> New -> New Project и выберите Empty Compose Activity. Далее следуйте инструкциям мастера и выберите «Готово».

Лямбды, Лямбды Везде!

Первое, что вы заметите, это то, что функция setContent теперь принимает лямбду . Так работает Jetpack Compose. Функции принимают составные функции как лямбды, а их свойства — как параметры.

Если вы углубитесь в код, нажав Cmd + Click, вы заметите, что setContent теперь принимает составную функцию в качестве параметра. Композиционные параметры также аннотируются с помощью @Composable .

Возвращаясь к нашему коду, мы передаем MaterialTheme, который обозначает, что наше приложение будет построено с использованием Material Design. Затем, наконец, мы передаем составное приветствие, которое по сути является TextView.

Двигаясь дальше, вы заметите метод, аннотированный @Preview.

1
2
3
4
5
6
7
@Preview("MyScreen preview")
@Composable
fun MyPreview() {
    MyApp {
        Content()
    }
}

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

Создание нашего макета

Тематическое наше приложение

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

1
2
3
4
5
6
7
8
@Composable
fun MyApp(children: @Composable() () -> Unit) {
    MaterialTheme {
        Surface(color = Color.White) {
            children()
        }
    }
}

Примечание. Эта функция находится за пределами нашего класса MainActivity.kt.

MyApp () — это составная функция, которая принимает другую составную функцию. Мы также установим фон для приложения, используя Surface, который является еще одним элементом из набора инструментов Compose UI. Наконец, мы переходим в лямбду, которую мы получаем. Это обеспечит инкапсуляцию всех детей внутри этой темы.

Добавление текста и кнопки

Далее, давайте начнем с добавления некоторого контента на наш экран. Создайте другую функцию с именем Content (), которая является составной функцией.

Чтобы разместить текст в центре экрана, создайте столбец, который заполняет всю высоту экрана. Это будет корневой контейнер.

1
2
3
4
5
6
@Composable
fun Content() {
    Column(modifier = ExpandedHeight, crossAxisAlignment = CrossAxisAlignment.Center) {
 
    }
}

Думайте о столбцах и строках как о LinearLayout с ориентацией по вертикали или горизонтали соответственно. Они складывают своих детей один за другим.

Строки и столбцы имеют две оси: MainAxis и CrossAxis. Это лучше объяснено на изображении ниже:

Далее нам нужно создать контейнер для добавления текста. Этот контейнер содержит только текст. Разверните этот контейнер, чтобы заполнить всю высоту экрана. Мы делаем это, передавая модификатор ExpandedHeight .

1
2
3
4
5
6
7
8
9
@Composable
fun Content() {
    Column(modifier = ExpandedHeight, crossAxisAlignment = CrossAxisAlignment.Center) {
        Column(modifier = Flexible(1f), crossAxisAlignment = CrossAxisAlignment.Center, mainAxisAlignment = MainAxisAlignment.Center) {
            Text(text = "I've been clicked 0 times!")
        }
 
    }
}

Для второго столбца мы добавили Flexible () в качестве модификатора. Это говорит о том, что столбец должен покрывать экран весом 1. Это можно рассматривать как вертикальный LinearLayout с весом 1.

Точно так же, в нашем корневом столбце мы добавим строку с MainAxis, выровненным до конца. Это поможет нам выровнять нашу кнопку до конца. Наконец, мы добавляем кнопку. Кнопка возвращается из функции Счетчик.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@Composable
fun Content(counterState: State = State()) {
    Column(modifier = ExpandedHeight, crossAxisAlignment = CrossAxisAlignment.Center) {
        Column(modifier = Flexible(1f), crossAxisAlignment = CrossAxisAlignment.Center, mainAxisAlignment = MainAxisAlignment.Center) {
            Text(text = "I've been clicked ${counterState.count} times!")
        }
 
        Row(modifier = ExpandedWidth, mainAxisAlignment = MainAxisAlignment.End) {
            Padding(padding = 16.dp) {
                Counter(counterState)
            }
        }
 
    }
}

Добавление взаимодействия с пользователем и управления состоянием

Теперь пришло время сделать что-то, когда пользователь нажимает кнопку. По сути, мы хотим увеличить наш счетчик при каждом нажатии кнопки.

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

1
2
@Model
class State(var count: Int = 0)

Обратите внимание на аннотацию @Model. Это указывает на то, что этот класс данных должен соблюдаться для изменений. Композиционные функции, которые читают данные из аннотированных классов @Model, будут выполнять компоновку при изменении данных. Таким образом, обновление пользовательского интерфейса.

Теперь мы передадим экземпляр этого объекта State в функцию Content. Мы изменим наше сообщение, чтобы включить счетчик между ними как таковой.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@Composable
fun Content(counterState: State = State()) {
    Column(modifier = ExpandedHeight, crossAxisAlignment = CrossAxisAlignment.Center) {
        Column(modifier = Flexible(1f), crossAxisAlignment = CrossAxisAlignment.Center, mainAxisAlignment = MainAxisAlignment.Center) {
            Text(text = "I've been clicked ${counterState.count} times!")
        }
 
        Row(modifier = ExpandedWidth, mainAxisAlignment = MainAxisAlignment.End) {
            Padding(padding = 16.dp) {
                Counter(counterState)
            }
        }
 
    }
}

Примечание. Мы использовали параметр по умолчанию в качестве экземпляра класса State, поэтому наш метод Content можно вызывать без параметров.

Далее, давайте добавим функциональность к нашей кнопке, чтобы увеличить счетчик. Передать объект состояния в функцию Counter. Наша кнопка принимает лямбда для onClick. Мы передадим лямбду, чтобы увеличить наш счетчик. Это заставит Text перекомпоновать и обновить пользовательский интерфейс.

1
2
3
4
@Composable
fun Counter(state: State) {
    Button(text = "Click Me!", style = ContainedButtonStyle(), onClick = {state.count++})
}

Я специально выбрал это Counter App, но почему?

Я намеренно решил создать это приложение счетчик. Причина в том, что это похоже на приложение, которое вы предварительно создали при создании нового проекта флаттера!

Я хотел бы сравнить различия в создании аналогичного приложения в Flutter против Jetpack Compose. И создание пользовательского интерфейса в Compose было приятно. Гораздо больше, чем во Флаттере. Но это может быть предвзятым мнением, поскольку я в основном разрабатываю нативные приложения на Kotlin.

Какой у вас опыт работы с Jetpack Compose? Упоминание в комментариях ниже! Давайте поговорим

Смотреть оригинальную статью здесь: Android Jetpack Compose — раз и навсегда!

Мнения, высказанные участниками Java Code Geeks, являются их собственными.