Написание чистого, эффективного кода  —  ключ к успеху разработчика Android, благодаря функциям-расширениям повышаются возможности имеющихся классов без изменения последних. Функции-расширения особенно кстати приходятся для Jetpack Compose, пользовательские интерфейсы с ними адаптивнее и эффективнее. Расширения необходимы и для упрощения кода системы представлений. Поэтому мы рассмотрим основные функции-расширения из асенала разработчика Jetpack Compose и пять функций-расширений для работы с системой представлений.

5 функций-расширений для Jetpack Compose

1. Modifier.clickableWithRipple

Волновой эффект  —  ключевой аспект дизайн-системы Material Design, которым пользователю сигнализируется, что элемент интерактивный. В то время как Modifier.clickable в Jetpack Compose предлагается базовый интерактивный эффект, добавлением волнового эффекта совершенствуется обратная связь пользовательского интерфейса. Этой функцией-расширением упрощается добавление волнового эффекта к любому интерактивному компоненту.

fun Modifier.clickableWithRipple(onClick: () -> Unit): Modifier {
return this.clickable(
indication = rememberRipple(), // Индикатор волнового эффекта
interactionSource = remember { MutableInteractionSource() }, // Обрабатываются многочисленные взаимодействия
onClick = onClick
)
}

Пример:

Text(
text = "Click Me",
modifier = Modifier.clickableWithRipple {
println("Text clicked!")
}
)

2. LazyColumn.scrollToTop

В Jetpack Compose LazyColumn обычно используется для отображения списков. Однако прокрутка к началу списка  —  задача не тривиальная. Этой функцией-расширением scrollToTop() вызывается прямо в LazyListState.

suspend fun LazyListState.scrollToTop() {
animateScrollToItem(0)
}

Пример:

val listState = rememberLazyListState()

LazyColumn(state = listState) {
items(100) { index ->
Text(text = "Item #$index")
}
}

// Активируется прокрутка вверх
LaunchedEffect(Unit) {
listState.scrollToTop()
}

3. Modifier.roundedBackgroundWithPadding

К любому composable в одной строке добавляются закругленные углы и отступы, чем упрощается стереотипный код.

fun Modifier.roundedBackgroundWithPadding(
backgroundColor: Color,
cornerRadius: Dp,
padding: Dp
): Modifier {
return this
.background(backgroundColor, shape = RoundedCornerShape(cornerRadius))
.padding(padding)
}

Пример:

Text(
text = "Rounded Background with Padding",
modifier = Modifier.roundedBackgroundWithPadding(
backgroundColor = Color.LightGray,
cornerRadius = 12.dp,
padding = 8.dp
)
)

4. Modifier.showIf

Видимость переключается при помощи логического условия с showIf. Благодаря этому расширению цепочка модификаторов сохраняется чистой и избегаются условия if непосредственно в composable.

fun Modifier.showIf(condition: Boolean): Modifier {
return if (condition) this else Modifier.size(0.dp)
}

Пример:

Text(
text = "Conditionally Visible",
modifier = Modifier.showIf(isVisible)
)

Если значение isVisible равно false, Text в composable фактически становится скрытым.

5. Modifier.animateVisibility

Чтобы добиться эффекта появления и затухания, исходя из условий видимости, применяется расширение animateVisibility. Благодаря alpha компонент постепенно отображается или исчезает.

fun Modifier.animateVisibility(isVisible: Boolean): Modifier {
return if (isVisible) {
this.alpha(1f)
} else {
this.alpha(0f)
}
}

Пример:

Text(
text = "Animated Visibility",
modifier = Modifier.animateVisibility(isVisible)
)

Бонус: 5 важных функций-расширений для системы представлений

1. View.visible() / View.gone()

Переключение между VISIBLE и GONE  —  привычная задача. Этими функциями-расширениями упрощается обработка изменений видимости непосредственно во View.

fun View.visible() {
this.visibility = View.VISIBLE
}

fun View.gone() {
this.visibility = View.GONE
}

Пример:

myView.visible()  // Представление становится видимым
myView.gone() // Представление исчезает при задании значения «GONE»

2. View.showIf(condition: Boolean)

Подобно модификатору showIf в Jetpack Compose, видимость View этим расширением переключается на основе логического условия.

fun View.showIf(condition: Boolean) {
this.visibility = if (condition) View.VISIBLE else View.GONE
}

Пример:

myView.showIf(isDataAvailable)

3. TextView.setTextColorRes(resId: Int)

Благодаря настройке цветов по идентификаторам ресурсов, поддерживается согласованность. Этой функцией цветовой ресурс настраивается непосредственно в TextView, чем повышается удобство восприятия.

fun TextView.setTextColorRes(@ColorRes resId: Int) {
this.setTextColor(ContextCompat.getColor(context, resId))
}

Пример:

myTextView.setTextColorRes(R.color.primaryColor)

4. EditText.clearText()

Очистка EditText  —  частая задача, обычно выполняется заданием пустой строки. Благодаря расширению clearText код сохраняется чистым и выразительным.

fun EditText.clearText() {
this.setText("")
}

Пример:

myEditText.clearText() // Текст в «EditText» очищается

5. ImageView.loadImage(url: String)

Загрузка изображений упрощается библиотеками вроде Glide или Coil. Этой функцией-расширением интегрируется Glide, поэтому изображения загружаются прямо с URL-адресом.

fun ImageView.loadImage(url: String) {
Glide.with(this.context)
.load(url)
.into(this)
}

Пример:

myImageView.loadImage("https://example.com/image.jpg")

Заключение

Функции-расширения  —  это мощный инструмент в разработке Android, с которым пишется более чистый и выразительный код. Включением этих функций упрощаются процесс разработки и взаимодействие с Jetpack Compose, а также с традиционной системой представлений.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Dobri Kostadinov: Top 5 Extension Functions Every Jetpack Compose Developer Should Have

Предыдущая статьяКонкурентность и синхронизация на Go: горутины, мьютексы и WaitGroup
Следующая статьяКак сделать зернистый градиент на CSS