Переопределение и объединение модификаторов

Последнее обновление: 05.04.2024

Модификаторы по умолчанию и переопределение модификаторов

Большинство (если не все) компонентов принимают модификатор через один из своих параметров. При этом для многих из подобных компонентов применяется некоторый модификатор по умолчанию. Если мы явным образом не передаем компоненту никаких функций-модификаторов, то применяется модификатор по умолчанию. И мы можем делать подобным образом при определении своих компонентов. Рассмотрим простейший пример:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.runtime.Composable

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Message("Hello METANIT.COM")
        }
    }
}

@Composable
fun Message(text:String, textModifier:Modifier=Modifier.fillMaxWidth().padding(10.dp)){
    Text(text, textModifier, fontSize = 28.sp, textAlign = TextAlign.Center)
}

Здесь определен компонент Message, который по сути является оберткой над встроенным компонентом Text. Функция Message принимает два параметра: выводимый текст и функции модификатора:

fun Message(text:String, textModifier:Modifier=Modifier.fillMaxWidth().padding(10.dp)){

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

В методе setContent() вызываем компонент Message, не передавая ему никаких модификаторов:

Message("Hello METANIT.COM")

В итоге будет применяться модификатор по умолчанию:

Определение модификатора по умолчанию для компонентов Jetpack Compose на Kotlin на Android

Теперь переопределим модификатор по умолчанию:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.runtime.Composable

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.ui.graphics.Color

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val myModifier = Modifier
                .fillMaxWidth()
                .padding(10.dp)
                .border(width = 2.dp, color = Color.DarkGray)
                .background(Color.LightGray)
                .padding(20.dp)
            Message("Hello METANIT.COM", myModifier)
        }
    }
}

@Composable
fun Message(text:String, textModifier:Modifier =Modifier.fillMaxWidth().padding(10.dp)){
    Text(text, textModifier, fontSize = 28.sp, textAlign = TextAlign.Center)
}

В данном случае в компонент Message передается модификатор myModifier, который устанавливает границу, фон и отступы от границ контейнера

Переопределение модификатора по умолчанию для компонентов Jetpack Compose на Kotlin на Android

Объединение модификаторов

Может возникнуть ситуация, когда к компоненту необходимо применить несколько модификаторов. Например, если мы определяем набор модификаторов по умолчанию, которые в любом случае применяются к компоненту, но также хотим, чтобы динамически при вызове компонента в него также передавалиь еще какие-нибудь модификаторы. Для объединения модификаторов у объекта Modifier применяется метод then. Например:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val customModifier = Modifier
                .border(width = 2.dp, color = Color.DarkGray, shape= CircleShape)
                .clip(shape= CircleShape)
                .background(Color.LightGray)
                .padding(20.dp)
            Message("Hello METANIT.COM", customModifier)
        }
    }
}

@Composable
fun Message(text:String, textModifier: Modifier=Modifier){
    val defaultModifier = Modifier.fillMaxWidth().padding(10.dp)
    Text(text, defaultModifier.then(textModifier), fontSize = 28.sp, textAlign = TextAlign.Center)
}

Здесь компонент Message также принимает два параметра: выводимый текст и функции модификатора, которые по умолчанию равны пустому модификатору.

fun Message(text:String, textModifier: Modifier=Modifier){

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

val defaultModifier = Modifier.fillMaxWidth().padding(10.dp)

Затем вызываем компонент Text, устанавливая у него текст, модификаторы и выравнивание текста по центру:

Text(text, defaultModifier.then(textModifier), fontSize = 28.sp, textAlign = TextAlign.Center)

При этом происходит объединение модификаторов - к defaultModifier присоединяются модификаторы из textModifier:

defaultModifier.then(textModifier)

В методе setContent() вызываем компонент Message, передавая ему модификатор customModifier:

val customModifier = Modifier
    .border(width = 2.dp, color = Color.DarkGray, shape= CircleShape)
    .clip(shape= CircleShape)
    .background(Color.LightGray)
    .padding(20.dp)
Message("Hello METANIT.COM", customModifier)

Кастомный модификатор customModifier устанавливает границу, получает округлый сегмент компонента и задает цвет и отступ от границы до содержимого. В конечном итоге defaultModifier объединяется с customModifier:

Объединение модификаторов для компонентов Jetpack Compose на Kotlin на Android
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850