'Set all text style changes in one place in Compose UI similar to styles.xml
Previously you could define all of your style changes as a single style in XML which was really convenient especially if you had a lot of different styles. The project I'm currently working on has 50+ of these styles defined.
<!-- styles.xml -->
<style name="title_1">
<item name="android:textColor">@color/purple_500</item>
<item name="android:fontFamily">@font</item>
<item name="android:textSize">18sp</item>
<item name="android:maxLines">1</item>
<item name="android:firstBaselineToTopHeight">12sp</item>
<item name="android:lastBaselineToBottomHeight">9sp</item>
</style>
<!-- hello_world.xml -->
<TextView
android:id="@+id/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, World!"
style="@style/title_1" />
While looking to transition to Compose UI, I noticed that certain attributes are separated out. For example baseline can be changed as a modifier while other values can be changed as a text style or a separate parameter in the case of max lines.
// Styles.kt
@Composable
fun Title1(text: String) {
Text(
text = text,
modifier = Modifier.paddingFromBaseline(top = 12.sp, bottom = 9.sp),
maxLines = 1,
style = TextStyle(
color = colorResource(id = R.color.purple_500),
fontFamily = FontFamily(Font(R.font.podkova_semibold)),
fontSize = 18.sp
)
)
}
// MainActivity.kt
setContent {
Title1("Hello, World")
}
This makes it more error prone since they're separated into different parameters and it's easy to forget to apply one of them. I know you could lump all the text styles together, which helps, but was wondering if there was a way to replicate what we had in XML and specify all the modifications in one place.
In my initial approach above I tried creating wrappers around the Text composable with all the predefined changes, but wanted a flexible solution that can take all the Text parameters without having 50+ composables with all the same parameters as the Text composable. Wondering if there's something in the Kotlin language that can help simplify this or if this is just the wrong approach to the problem.
// Would like to avoid having to do this 50+ times
@Composable
fun Title1(
text: String,
modifier: Modifier = Modifier,
color: Color = Color.Unspecified,
fontSize: TextUnit = TextUnit.Unspecified,
fontStyle: FontStyle? = null,
fontWeight: FontWeight? = null,
fontFamily: FontFamily? = null,
letterSpacing: TextUnit = TextUnit.Unspecified,
textDecoration: TextDecoration? = null,
textAlign: TextAlign? = null,
lineHeight: TextUnit = TextUnit.Unspecified,
overflow: TextOverflow = TextOverflow.Clip,
softWrap: Boolean = true,
maxLines: Int = 1,
onTextLayout: (TextLayoutResult) -> Unit = {},
style: TextStyle = LocalTextStyle.current
) {
Text(
text = text,
modifier = modifier
.paddingFromBaseline(top = 12.sp, bottom = 9.sp),
color = color,
fontSize = fontSize,
fontStyle = fontStyle,
fontWeight = fontWeight,
fontFamily = fontFamily,
letterSpacing = letterSpacing,
textDecoration = textDecoration,
textAlign = textAlign,
lineHeight = lineHeight,
overflow = overflow,
softWrap = softWrap,
maxLines = maxLines,
onTextLayout = onTextLayout,
style = style.merge(
TextStyle(
color = colorResource(id = R.color.purple_500),
fontFamily = FontFamily(Font(R.font.podkova_semibold)),
fontSize = 18.sp
)
)
)
}
Solution 1:[1]
I think your initial approach is correct in the current version of Jetpack Compose (1.1.1), but they're currently working on APIs to enable setting this within a Text
's TextStyle
, so you can keep it all in one place, similar to XML.
See Compose UI 1.2.0-beta01: https://developer.android.com/jetpack/androidx/releases/compose-ui#version_12_2
It looks like they'll be adding a lineHeightStyle
property to TextStyle
, in addition to platformStyle
(which allows setting includeFontPadding
to false
).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | D.J.M. Francis |