开发中在设置文本样式时,添加投影是一种还算常用的效果,给文字一种文字在内容之上的错觉,类似于 Card
常用的 elevation
效果,设置相对容器平面的高度,让人看起来有阴影的效果。
本文我们将介绍如何使用 Jetpack Compose
实现这种效果。
1. XML 布局中 TextView 的阴影效果
我们先来看看使用 XML 定义布局的传统方式时 TextView
的阴影效果是怎样实现的。
使用 XML 布局时 TextView
实现阴影效果时很简单的,TextView
本身就拥有支持阴影效果的属性:
<TextView
android:shadowRadius="3"
android:shadowDx="5"
android:shadowDy="5" />
通过组合使用这三个参数我们可以轻松实现阴影效果:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello ITmob.cn"
android:textSize="32sp"
android:textColor="@color/black"
android:shadowColor="#FF6100"
android:shadowRadius="3"
android:shadowDx="5"
android:shadowDy="5"/>
效果:
如上是过去使用 XML layout 如何实现文本阴影效果,接下来介绍一下 Jetpack Compose 中如何实现相同的效果。
我们可用使用两种方式实现这个效果:
1. 使用 Jetpack Compose 的 AndroidView
2. 使用 Jetpack Compose 的 Text
2. 使用 AndroidView 实现文字阴影
AndroidView
允许我们在 Jetpack Compose 代码中使用 Android 中之前版本的控件。如果需要使用尚未在 Jetpack Compose 中实现的控件,这种方式非常有用。
如下是实现它的代码:
@Composable
private fun ImplementedViaAndroidView() {
AndroidView(
modifier = Modifier.fillMaxWidth(),
factory = { context ->
TextView(context).apply {
layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
text = "Hello ITmob.cn"
gravity = CENTER_HORIZONTAL
textSize = 32.sp.value
setTextColor(Color.BLACK)
setShadowLayer(3F, 5F, 5F, 0xFFFF6100.toInt())
}
}
)
}
效果:
这种方式只是将 TextView
包装到一个可组合的 AndroidView
中。直接使用之前 XML 布局实现中的 TextView
并设置相同的参数。这样就可以达到与 XML 布局相同的效果。
3. 使用 Text 的 TextStyle 实现文字阴影
前两种实现方式都依赖与 Android 中旧的控件实现方式,如果不想使用 XML 布局或 AndroidView
也可以通过纯 Text
可组合函数来实现相同的目标。
代码如下:
@Composable
private fun ImplementedViaTextStyle() {
Text(
color = colorResource(R.color.black),
fontSize = 32.sp,
style = TextStyle(
shadow = Shadow(
color = Color(0xFFFF6100),
offset = Offset(x = 5F, y = 5F),
blurRadius = 3F,
)
),
text = "Hello ITmob.cn",
)
}
效果:
如代码所示,Text
可组合函授的 style
属性可用设置文本的阴影效果,**TextStyle
还有更多的属性用于设置文字效果,如:textDirection
textIndent
等不能直接通过 Text
可组合函数设置的效果。**
在实际开发中我们往往有统一的主题和文字样式,实现阴影效果时并不想破坏它跟其他文本统一的样式,可用使用
copy
方法在原有样式上修改:
Text(
color = colorResource(R.color.black),
fontSize = 32.sp,
style = MaterialTheme.typography.bodyLarge.copy(
shadow = Shadow(
color = Color(0xFFFF6100),
offset = Offset(x = 5F, y = 5F),
blurRadius = 3F,
)
),
text = "Hello ITmob.cn",
)