在這篇文章中,介紹了兩種方式製作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方法可以參考這篇
更進階的用法可參考這篇
沒有留言:
張貼留言