Is there a way to create and apply a style to multiple elements in Compose like we do with CSS

Viewed 38

I have multiple rows filled with multiple texts and I need all those texts to have the same padding, color, font size and mostly everything else:

Row{
    for(i in 1..7) Text(stuff[i-1])
}
Row{
    for(i in 8..15) Text(stuff[i-1])
}
Row{
    for(i in 16..23) Text(stuff[i-1])
}
Row{
    for(i in 24..30) Text(stuff[i-1])
}

I really don't want to have bloated code with all the redundant modifiers repeating over and over, is there a way to use something like a CSS class and paste it onto every element I want?

Thanx in advance.

1 Answers

In Jetpack Compose Modifiers are used for

  1. Change the composable's size, layout, behavior, and appearance
  2. Add information, like accessibility labels
  3. Process user input
  4. Add high-level interactions, like making an element clickable, scrollable, draggable, or zoomable

You can use a Modifier for multiple items

by declaring them globally or inside a function such as

val modifier = Modifier
    .shadow(1.dp, CircleShape)
    .border(1.dp, Color.Yellow)
    .size(100.dp)
    .background(Color.Red)
    .padding(10.dp)

or creating your own modifier

fun Modifier.myStyle() = this.then(
Modifier
        .shadow(1.dp, CircleShape)
        .border(1.dp, Color.Yellow)
        .size(100.dp)
        .background(Color.Red)
        .padding(10.dp)
)

Multiple Composable can use declared or Modifier extension functions

Row(modifier){}
Column(modifier){}
Row(modifier){}
Row(Modifier.myStyle()){}
Row(Modifier.myStyle()){}

However font size is not a general attribute you can apply to any Composable, specific attributes like this can be stored in a class for Composable. Text Composable stores its attributes in a class named TextStyle and this can be applied to any Text when you create an instance of TextStyle.

You can create your own data classes to store Composable specific attributes either.

data class MyAttributes(val fontSize:TextUnit=10.sp, val elevation = CardElevation.elevation,...,val sliderColors)

You can also use CompositionLocal to pass specific styling to scope of Composables too

data class Elevations(val card: Dp = 0.dp, val default: Dp = 0.dp)

// Define a CompositionLocal global object with a default
// This instance can be accessed by all composables in the app
val LocalElevations = compositionLocalOf { Elevations() }


class MyActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            // Calculate elevations based on the system theme
            val elevations = if (isSystemInDarkTheme()) {
                Elevations(card = 1.dp, default = 1.dp)
            } else {
                Elevations(card = 0.dp, default = 0.dp)
            }

            // Bind elevation as the value for LocalElevations
            CompositionLocalProvider(LocalElevations provides elevations) {
                // ... Content goes here ...
                // This part of Composition will see the `elevations` instance
                // when accessing LocalElevations.current
            }
        }
    }
}
Related