**截止 Jetpack Compose Glance1.1.0官方小组件目前Glance Text不支持自定义字体,只默认支持官方自带,如下
package androidx.glance.text
/**
* Describes the family of the font.
* Defaults are provided, but it is also possible to supply a custom family. If this is found on
* the system it will be used, otherwise it will fallback to a system default.
*/
class FontFamily constructor(val family: String) {
companion object {
/**
* The formal text style for scripts.
*/
val Serif = FontFamily("serif")
/**
* Font family with low contrast and plain stroke endings.
*/
val SansSerif = FontFamily("sans-serif")
/**
* Font family where glyphs have the same fixed width.
*/
val Monospace = FontFamily("monospace")
/**
* Cursive, hand-written like font family.
*/
val Cursive = FontFamily("cursive")
}
override fun toString(): String {
return family
}
}
要实现自定UI字体,需要使用自定义文本Bitmap,就是以图片的加载自定义字体【在 Jetpack Compose Glance 1.1.0 中,官方小组件的 Glance Text 不支持自定义字体,仅支持默认的 Serif、SansSerif、Monospace 和 Cursive 字体。要实现自定义字体,可以通过将文本渲染为 Bitmap 的方式来实现。具体步骤包括:使用 Paint 类设置字体、颜色和大小,然后通过 Canvas 将文本绘制到 Bitmap 上。最后,将生成的 Bitmap 作为 Image 显示在小组件中。这种方法虽然绕过了 Glance Text 的限制,但增加了实现的复杂性】。
字体放置位置:
实现自定义字体carter_one.ttf方式如下
核心代码
@SuppressLint("ResourceAsColor")
fun createTextBitmap(context: Context, text: String, fontResId: Int): Bitmap {
val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = ContextCompat.getColor(context, R.color.white) // 从资源获取白色
textSize = 50f //字体大小
typeface = ResourcesCompat.getFont(context, fontResId)
}
val width = paint.measureText(text).toInt()
val height = paint.fontMetrics.run { (descent - ascent).toInt() }
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
canvas.drawText(text, 0f, -paint.fontMetrics.ascent, paint)
return bitmap
}
完整代码:
class CattleLikeWorkerGlanceSmallWidgetStyleOne : GlanceAppWidget() {
@SuppressLint("ResourceAsColor")
fun createTextBitmap(context: Context, text: String, fontResId: Int): Bitmap {
val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = ContextCompat.getColor(context, R.color.white) // 从资源获取白色
textSize = 50f //字体大小
typeface = ResourcesCompat.getFont(context, fontResId)
}
val width = paint.measureText(text).toInt()
val height = paint.fontMetrics.run { (descent - ascent).toInt() }
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
canvas.drawText(text, 0f, -paint.fontMetrics.ascent, paint)
return bitmap
}
private fun createRemoteViews(context: Context): RemoteViews {
return RemoteViews(
context.packageName,
R.layout.custom_widget_layout
).apply {
}
}
fun forceUpdate() {
CoroutineScope(Dispatchers.Default).launch {
GlanceAppWidgetManager(context).getGlanceIds(CattleLikeWorkerGlanceSmallWidgetStyleOne::class.java)
.forEach { glanceId ->
update(context, glanceId)
}
}
}
@SuppressLint("UnrememberedMutableState")
override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
Content()
}
}
@Composable
fun CustomTextWidget() {
// 使用 RemoteViews 引用自定义布局
}
@Composable
private fun Content() {
Box(
modifier = GlanceModifier
.fillMaxSize()
.background(ColorProvider(Color(0XFF000000)))
.cornerRadius(22.dp)
) {
Box(
modifier = GlanceModifier
.padding(vertical = 16.67.dp, horizontal = 16.67.dp)
.fillMaxSize(),
contentAlignment = Alignment.TopStart
) {
Column {
Text(
text = "小组件字体测试【常规字体】",
style = TextStyle(
color = ColorProvider(Color(0xFFE9E9E9)),
fontWeight = FontWeight.Normal,
fontSize = 10.sp
),
maxLines = 1, // 限制为单行
)
val bitmap = createTextBitmap(context, "小组件字体测试【自定义字体】", R.font.carter_one)
Image(
provider = ImageProvider(bitmap),
contentDescription = null,
modifier = GlanceModifier
)
}
}
Box(
modifier = GlanceModifier
//.padding(10.dp)
.fillMaxSize(),
contentAlignment = Alignment.CenterStart
) {
}
Box(
modifier = GlanceModifier
.padding(13.dp)
.fillMaxSize(),
contentAlignment = Alignment.BottomStart
) {
Column(
modifier = GlanceModifier
.fillMaxWidth(),
verticalAlignment = Alignment.Vertical.CenterVertically
) {
Column(
modifier = GlanceModifier
.background(ColorProvider(Color(0xFFFF4C01)))
.cornerRadius(7.dp)
.padding(horizontal = 12.dp, vertical = 3.dp),
) {
val bitmap = createTextBitmap(context, "¥ 290.17", R.font.carter_one)
Image(
provider = ImageProvider(bitmap),
contentDescription = null,
modifier = GlanceModifier
)
Text(
text = "¥ 290.17",
style = TextStyle(
color = ColorProvider(Color.Black),
fontSize = 13.sp,
fontWeight = FontWeight.Medium
),
maxLines = 1
)
}
}
}
}
}
}
注意Glance里使用RemoteViews加载原始的带字体样式【android:fontFamily=“@font/carter_one”】的xml布局也是不行的。
整体效果如下: