在Compose UI中的一个位置设置所有文本样式更改,类似于styles.xml



以前,您可以将所有样式更改定义为XML中的单个样式,这非常方便,尤其是当您有很多不同的样式时。我目前正在进行的项目已经定义了50多种这样的样式。

<!-- 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" />

在希望过渡到Compose UI时,我注意到某些属性是分离的。例如,基线可以作为修改器更改,而其他值可以作为文本样式或单独的参数更改(在最大行的情况下(。

// 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")
}

这使得它更容易出错,因为它们被分离成不同的参数,并且很容易忘记应用其中一个参数。我知道你可以把所有的文本样式放在一起,这很有帮助,但我想知道是否有一种方法可以复制我们在XML中的内容,并在一个地方指定所有的修改。

在我上面的初始方法中,我尝试在具有所有预定义更改的Text compositable周围创建包装器,但希望有一个灵活的解决方案,可以接受所有Text参数,而不需要具有与Text compositble相同参数的50多个可组合包。想知道Kotlin语言中是否有什么可以帮助简化这一点,或者这只是解决问题的错误方法。

// 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
)
)
)
}

我认为在当前版本的Jetpack Compose(1.1.1(中,您的初始方法是正确的,但他们目前正在开发API,以便能够在TextTextStyle中设置这一点,因此您可以将其全部保存在一个位置,类似于XML。

请参阅Compose UI 1.2.0-beta01:https://developer.android.com/jetpack/androidx/releases/compose-ui#version_12_2

看起来除了platformStyle(允许将includeFontPadding设置为false(之外,他们还将向TextStyle添加lineHeightStyle属性。

您可以通过排版来创建它。

object MyStyle{
val myFontFamily = FontFamily(
Font(R.font.custom_font, FontWeight.Bold)
)

val myTypepo = Typography(
bodyLarge = TextStyle(
fontFamily = myFontFamily,
fontWeight = FontWeight.Bold,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
),)

}

现在OnTextView你可以像一样使用它

Text(text = title, style = MyStyle.myTypepo.bodyLarge)

当您应用主题时,您可以使用此代码,它将在整个应用程序中实现

MaterialTheme(
colorScheme = MyColorScheme,
typography = MyTypo,
content = {
ProvideTextStyle(value = defaultTextStyle, content)
}
)

最新更新