Освой Compose играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Для работы понадобится Android Studio Giraffe и старше (впервые возможность появилась в Arctic Fox), в котором есть готовый шаблон Empty Activity (до версии Flamingo было два шаблона Empty Compose Activity).
Версия Flamingo.
Версия Electric Eel, Dolphin и раньше.
Запустим проект на основе предлагаемого шаблона и изучим его.
В build.gradle прописано следующее (другие настройки пока не рассматриваем).
android {
buildFeatures {
compose true
}
...
}
Посмотрим на код программы. Первое, что бросается в глаза - нет XML-файла для разметки. Есть только код для MainActivity.kt. Выделена строка, которая добавилась в Android Studio и мои изменения в строках.
package ru.alexanderklimov.compose
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import ru.alexanderklimov.compose.ui.theme.ComposeTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Kitty")
}
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello \$name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
ComposeTheme {
Greeting("Kitty")
}
}
Наш класс наследуется от класса ComponentActivity. По-прежнему есть метод onCreate(), в котором вызывается уже не метод setContentView(), а другой метод setContent(), определяющий макет экрана. Только вместо загрузки XML-файла, мы вызываем composable-функции. В студии эти методы выводятся зелёным цветом и начинаются с большой буквы - к этому придётся привыкать.
Встречаются composable-функции ComposeTheme, Surface и Greeting (внутри неё функция Text).
Например, функция Text() определена в библиотеке Compose UI и вам нужно лишь указать текст. Всё очень просто.
Работа функции Greeting понятна - выводит текст "Hello Android". Вообще-то положено выводить текст "Hello World", но Гугл в 2021 году осмелилась нарушить традицию и изменить привычное выражение. Но компания отстала от меня на 10 лет, я начал выводить "Hello Kitty" гораздо раньше. Вот и в первом нашем проекте я также внёс единственное изменение.
По поводу ComposeTheme - она задаёт тему, а её имя создаётся на основе имени вашего проекта. Если посмотрите на структуру проекта, то увидите, что кроме файла MainActivity.kt есть подпапка ui.theme с набором файлов, в том числе и Theme.kt. В нём можно найти описание используемой темы на основе MaterialTheme.
Функция Surface отвечает за фон приложения. По умолчанию это белый цвет (в том же файле Theme.kt есть сноска на этот счёт.
В шаблоне реализован самый простой пример для знакомства, мы упростим ещё больше - просто выводим строку на экран.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Text("Hello Kitty!")
}
}
}
Составные функции можно вызывать только из области видимости других составных функций. Чтобы сделать функцию составной, нужно добавить аннотацию @Composable.
В примере есть пример такой собственной составной функции с одним параметром для установки имени. С её помощью можно здороваться с котом.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Greeting("Барсик")
}
}
}
@Composable
fun Greeting(name: String) {
Text (text = "Привет \$name!")
}
Чтобы увидеть результат, нам необходимо запустить приложение на эмуляторе или на устройстве. Это не очень удобно при частых правках. Студия позволяет увидеть будущий вид экрана через аннотацию @Preview. Аннотация @Preview должна находиться до аннотации @Composable. Но есть небольшое ограничение у аннотации - составная функция не должна содержать параметры. По этой причине мы не сможем увидеть предыдущий пример, где функция использует один параметр. Пойдём на хитрость и вызовем функцию в другой функции.
@Composable
fun Greeting(name: String) {
Text(text = "Hello \$name!")
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
ComposeTheme {
Greeting("Kitty")
}
}
@Preview
@Composable
fun PreviewGreeting() {
Greeting("Барсик")
}
Превью-функцию желательно создавать как отдельный элемент кода, который не будет вызываться в приложении. Она служит для просмотра внешнего вида и только. Чтобы увидеть визуальную картинку, используйте значки Split или Design, как обычно мы делали для просмотра XML-файла.
После сделанных изменений в коде не забывайте нажимать кнопку Refresh в верхней части редактора.
Если присмотреться, то можно увидеть, что определённая часть кода всегда остаётся неизменной. Для экономии места я буду использовать сокращённый вариант для примеров. Для начала полный код.
package ru.alexanderklimov.compose
import ...
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Content()
}
}
}
@Composable
fun Content()
{
// Здесь код для примера
}
@Preview(showBackground = true)
@Composable
fun ContentPreview() {
Content()
}
Для демонстрации простейших примеров достаточно показать код из Content(). На всякий случай также буду добавлять список импортированных классов, так как порой имена совпадают и на первых порах можно делать ошибочный импорт.
// Один из примеров
@Composable
fun Content() {
Text(text = "Hello Kitty")
}
Урокам по Compose выделен отдельный раздел. Сейчас практически все быстро мигрируют на новый способ написания приложений. Первоначально непривычно, но потом начинаешь привыкать. Надеюсь, вам понравится.