第一个,Text
的跑马灯效果,对标传统 TextView
的跑马灯效果,通过 Modifier.basicMarquee()
即可实现,代码非常简单:
Text(
text="This text is very long.".repeat(100),
maxLines = 1,
modifier = Modifier.basicMarquee()
)
效果:
第二个,放大镜效果,主要是 Modifier.magnifier
这个修饰符,参考代码如下:
var offset by remember { mutableStateOf(Offset.Zero) }
Box(
modifier = Modifier
.fillMaxWidth()
.pointerInput(Unit) {
detectDragGestures { change, dragAmount ->
offset = change.position
}
}
.magnifier(
sourceCenter = {
offset
},
magnifierCenter = {
offset - Offset(x = 0f, y = 200f)
}
)
) {
Image(
painter = painterResource(R.drawable.kermit),
contentDescription = null,
modifier = Modifier.fillMaxWidth(),
contentScale = ContentScale.FillWidth
)
}
效果如下:
如果要实现常见的圆形放大镜效果,只需将上面代码稍加修改,为 magnifier
加一个 style
属性配置即可:
var offset by remember { mutableStateOf(Offset.Zero) }
Box(
modifier = Modifier
.fillMaxWidth()
.pointerInput(Unit) {
detectDragGestures { change, dragAmount ->
offset = change.position
}
}
.magnifier(
sourceCenter = {
offset
},
magnifierCenter = {
offset - Offset(x = 0f, y = 200f)
},
style = MagnifierStyle(
size = DpSize(100.dp, 100.dp),
cornerRadius = 100.dp
)
)
) {
Image(
painter = painterResource(R.drawable.kermit),
contentDescription = null,
modifier = Modifier.fillMaxWidth(),
contentScale = ContentScale.FillWidth
)
}
效果如下:
第三个,Modifier.drawWithContent
,这个修饰符可以让我们在原本组件内容绘制的之前和之后的时机做一些自己的绘制操作,比如在原来的文字图片后面画个背景,或者在原来的内容之上画个圆画个圈、添加一些小装饰啥的,别提有多方便了。
下面是一个简单的示例:
@Preview(showBackground = true)
@Composable
fun DrawBefore() {
Box(
modifier = Modifier.size(120.dp),
contentAlignment = Alignment.Center
) {
Card(
shape = RoundedCornerShape(8.dp),
modifier = Modifier
.size(100.dp)
.drawWithContent {
// 显示在drawContent()的下层,即背景
drawRect(
Color.Green,
size = Size(110.dp.toPx(), 110.dp.toPx()),
topLeft = Offset(x = -5.dp.toPx(), y = -5.dp.toPx()),
//style = Stroke(width = 5f)
)
// 在 drawContent() 的前后自定义绘制一些内容,可以控制绘制的层级
drawContent()
drawCircle( // 显示在drawContent()的上层层,即前景
Color(0xffe7614e),
radius = 18.dp.toPx() / 2,
center = Offset(drawContext.size.width, 0f)
)
}
) {
Image(
painter = painterResource(id = R.drawable.ic_head3),
contentDescription = "head",
contentScale = ContentScale.Crop
)
}
}
}
drawWithContent
修饰符的lambda中,drawContent()
这一句是必须调用的,它是组件原本的绘制内容,而在它的前后可以分别Canvas的Api进行自定义绘制,最终会分别显示为原本内容的背景和前景。
显示效果如下:
其实像这样方便的 DrawModifier 修饰符,Compose 总共提供了三个: drawWithContent
、drawBehind
、drawWithCache
。不一一介绍了,感兴趣可以看这篇:Jetpack Compose 中的 Canvas ,这篇文章里我已经全部整理好了。