我需要对整个应用程序中使用的所有 Text() 应用通用字体。目前,我正在使用如下样式或字体将其手动应用到每个文本。我如何将其指定为应用程序的全局主题?在正常的 xml 布局中,我使用自定义 TextView 小部件来实现此目的。
Text(
text = stringResource(id = R.string.userName),
style = typography.h2,
fontSize = 20.sp,
)
您可以使用
typography
中的 MaterialTheme
参数来指定默认字体。
在Material2中,您可以使用
defaultFontFamily
参数来指定默认字体,如@Ajith所示。但该参数在Material3(Material Design 3)中被删除了。
注意:与 M2 Typography 类不同,M3 Typography 类不 目前包含一个
参数。你需要使用 相反,每个单独的 TextStyle 中的defaultFontFamily
参数。 (来源)fontFamily
但是您可以对 Material3 执行以下操作。以下是在 M3 中设置默认字体系列的示例:
// Type.kt
import androidx.compose.material3.Typography
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import com.example.exampleapp.R
// Declare the font families
object AppFont {
val TitilliumWeb = FontFamily(
Font(R.font.titillium_web_regular),
Font(R.font.titillium_web_italic, style = FontStyle.Italic),
Font(R.font.titillium_web_medium, FontWeight.Medium),
Font(R.font.titillium_web_medium_italic, FontWeight.Medium, style = FontStyle.Italic),
Font(R.font.titillium_web_bold, FontWeight.Bold),
Font(R.font.titillium_web_bold_italic, FontWeight.Bold, style = FontStyle.Italic)
)
}
private val defaultTypography = Typography()
val Typography = Typography(
displayLarge = defaultTypography.displayLarge.copy(fontFamily = AppFont.TitilliumWeb),
displayMedium = defaultTypography.displayMedium.copy(fontFamily = AppFont.TitilliumWeb),
displaySmall = defaultTypography.displaySmall.copy(fontFamily = AppFont.TitilliumWeb),
headlineLarge = defaultTypography.headlineLarge.copy(fontFamily = AppFont.TitilliumWeb),
headlineMedium = defaultTypography.headlineMedium.copy(fontFamily = AppFont.TitilliumWeb),
headlineSmall = defaultTypography.headlineSmall.copy(fontFamily = AppFont.TitilliumWeb),
titleLarge = defaultTypography.titleLarge.copy(fontFamily = AppFont.TitilliumWeb),
titleMedium = defaultTypography.titleMedium.copy(fontFamily = AppFont.TitilliumWeb),
titleSmall = defaultTypography.titleSmall.copy(fontFamily = AppFont.TitilliumWeb),
bodyLarge = defaultTypography.bodyLarge.copy(fontFamily = AppFont.TitilliumWeb),
bodyMedium = defaultTypography.bodyMedium.copy(fontFamily = AppFont.TitilliumWeb),
bodySmall = defaultTypography.bodySmall.copy(fontFamily = AppFont.TitilliumWeb),
labelLarge = defaultTypography.labelLarge.copy(fontFamily = AppFont.TitilliumWeb),
labelMedium = defaultTypography.labelMedium.copy(fontFamily = AppFont.TitilliumWeb),
labelSmall = defaultTypography.labelSmall.copy(fontFamily = AppFont.TitilliumWeb)
)
// Theme.kt
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
@Composable
fun AppTheme(
content: @Composable () -> Unit
) {
MaterialTheme(
typography = Typography,
content = content
)
}
单个组件的示例:
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import com.example.exampleapp.theme.AppFont
@Composable
fun ExampleScreen() {
Text(
text = "Hello World!",
fontFamily = AppFont.TitilliumWeb
)
}
Jetpack Compose 支持主题化,可以通过在应用程序主题中指定自定义字体来应用统一字体。执行此操作的步骤如下。
private val myCustomFont = FontFamily(
Font(R.font.helvetica_nue),
)
val Typography = Typography(
defaultFontFamily = myCustomFont,
)
@Composable
fun MyApplicationTheme(content: @Composable () -> Unit) {
MaterialTheme(
typography = Typography,
)
}
MyApplicationTheme {
NewsDetailScreen()
}
现在,无论应用主题,您的应用程序都会以指定字体显示文本。
参考:https://developer.android.com/jetpack/compose/themes/material#typography
如果您想始终使用相同的字体,请指定 defaultFontFamily 参数并省略任何 TextStyle 元素的 fontFamily:
一种类似的方法是首先在 Text 可组合项上创建自定义实现,我们将其称为 CustomText。 然后,对于您的用例,您可以在最常用的文本样式上编写包装器,例如
@Composable
TextH2(text : String) {
//call your own wrapper over framework Text composable
CustomText(text = text, typography = h2)
}
为了让事情变得更简单,您可以将字体资源、粗细和大小包装在一起,然后创建此类的具体实现 例如
val h2 = CustomTypography(font = R.font.your-ttf-file, fontSize = 20.sp, fontWeight = Medium)
上面的样式数据在一个可组合项中处理,在我们的例子中是 CustomText。
由于这里Material 3的答案是为每种样式单独设置字体,所以我想提出另一种方法。我知道这也不是最好的解决方案,但在 Material 3 提供更好的支持来设置全局字体之前,它可能是更好的解决方案。
此代码片段基于 Android Studio 的默认项目:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
PlaygroundTheme {
// A surface container using the 'background' color from the theme
CompositionLocalProvider(
LocalTextStyle provides LocalTextStyle.current.merge(
TextStyle(fontFamily = FontFamily(
Font(R.font.rubik))
)
)
) {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Hello Android!")
}
}
}
}
}
}
特别注意 CompositionLocalProvider,您可以用另一个本地样式覆盖该样式,只是在这种情况下,该样式将应用于 CompositionLocalProvider 中的所有元素。