Большинство (если не все) компонентов принимают модификатор через один из своих параметров. При этом для многих из подобных компонентов применяется некоторый модификатор по умолчанию. Если мы явным образом не передаем компоненту никаких функций-модификаторов, то применяется модификатор по умолчанию. И мы можем делать подобным образом при определении своих компонентов. Рассмотрим простейший пример:
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")
В итоге будет применяться модификатор по умолчанию:
Теперь переопределим модификатор по умолчанию:
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, который устанавливает границу, фон и отступы от границ контейнера
Может возникнуть ситуация, когда к компоненту необходимо применить несколько модификаторов. Например, если мы определяем набор модификаторов по умолчанию, которые в любом случае применяются к компоненту,
но также хотим, чтобы динамически при вызове компонента в него также передавалиь еще какие-нибудь модификаторы. Для объединения модификаторов у объекта 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: