在這篇文章中,介紹了兩種方式製作OutlinedText。
第一種:使用drawStyle(限制andriodx.core:core-ktx版本需要1.4.0-alpha01以上才有)
Text(
text = "Sample",
style = TextStyle.Default.copy(
fontSize = 64.sp,
drawStyle = Stroke(
miter = 10f,
width = 5f,
join = StrokeJoin.Round
)
)
)
缺點:沒有繪製文字,只有文字外框
第二種:使用Canvas
// Creating a outline text
@Composable
fun OutLineText() {
// Create a Paint that has black stroke
val textPaintStroke = Paint().asFrameworkPaint().apply {
isAntiAlias = true
style = android.graphics.Paint.Style.STROKE
textSize = 100f
color = android.graphics.Color.CYAN
strokeWidth = 12f
strokeMiter = 10f
strokeJoin = android.graphics.Paint.Join.ROUND
}
// Create a Paint that has white fill
val textPaint = Paint().asFrameworkPaint().apply {
isAntiAlias = true
style = android.graphics.Paint.Style.FILL
textSize = 100f
color = android.graphics.Color.WHITE
}
// Create a canvas, draw the black stroke and
// override it with the white fill
Canvas(
modifier = Modifier.fillMaxSize(),
onDraw = {
drawIntoCanvas {
it.nativeCanvas.drawText(
"Hello World",
200f,
200.dp.toPx(),
textPaintStroke
)
it.nativeCanvas.drawText(
"Hello World",
200f,
200.dp.toPx(),
textPaint
)
}
}
)
}
缺點: 這方式能繪出文字及顏色,
但因為使用了Canvas,所以是以畫面有效區域內的座標為位置,
無法使用Arrangement.Center,快速置中,
必須自行算出中點扣除文字長度一半後的座標點位。
(無法將文字當物件使用)
將上兩種方法重新整合後,出現第三種方法
@Composable
fun OutLineText(
text: String,
modifier: Modifier = Modifier,
fontSize: TextUnit,
color: Color = Color.White,
textAlign: TextAlign = TextAlign.Start,
outlinedBrush: Brush = Brush.horizontalGradient(
listOf(
Color.Blue,
Color.Magenta,
Color.Red,
Color.Yellow
)
),
) {
val textLayoutResultState = remember { mutableStateOf(null) }
Text(
text = text,
fontSize = fontSize,
color = color,
textAlign = textAlign,
onTextLayout = { textLayoutResultState.value = it },
modifier = modifier
.drawWithCache {
onDrawBehind {
drawIntoCanvas {
drawText(
textLayoutResultState.value!!,
outlinedBrush,
drawStyle = Stroke(
miter = 20f,
width = 15f,
join = StrokeJoin.Round
),
)
}
}
}
.width(IntrinsicSize.Max)
)
}
draw方法有兩種,drawWithContent和drawBehind,
drawWithContent多了一個drawContent()的方法,
讓你決定文字本體的繪製順序,
則drawBehind會繪製有在文字本體之下,背景之上,
drawWithCache提供兩個方法,
onDrawWithContent和onDrawBehind,
使用方式相同,只是結果會存在Cache中,
UI重新繪製時先檢查Cache是否有相同的結果,
如果有,就不重新計算,進而增加效能。,
想了解draw方法可以參考這篇
更進階的用法可參考這篇
沒有留言:
張貼留言