Установите все изменения стилей текста в одном месте в пользовательском интерфейсе Compose, аналогичном 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 со всеми предопределенными изменениями, но мне нужно было гибкое решение, которое могло бы принимать все параметры текста, не имея более 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
)
)
)
}
3 ответа
Вы можете создать его, сделав типографику.
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)
}
)
Я думаю, что ваш первоначальный подход правильный в текущей версии Jetpack Compose (1.1.1), но в настоящее время они работают над API, позволяющими установить это в пределах
Text
, поэтому вы можете хранить все это в одном месте, подобно XML.
См. Compose UI 1.2.0-beta01: https://developer.android.com/jetpack/androidx/releases/compose-ui#version_12_2 .
Похоже, они добавят
lineHeightStyle
собственность на
TextStyle
, в дополнение к
platformStyle
(что позволяет установить
includeFontPadding
к
false
).