Text 文本显示控件
@Composable
fun Text(
text: String?,
modifier: Modifier? = Modifier,
color: Color? = Color.Unspecified,
fontSize: TextUnit? = TextUnit.Unspecified,
fontStyle: FontStyle? = null,
fontWeight: FontWeight? = null,
fontFamily: FontFamily? = null,
letterSpacing: TextUnit? = TextUnit.Unspecified,
textDecoration: TextDecoration? = null,
textAlign: TextAlign? = null,
lineHeight: TextUnit? = TextUnit.Unspecified,
overflow: TextOverflow? = TextOverflow.Clip,
softWrap: Boolean? = true,
maxLines: Int? = Int.MAX_VALUE,
onTextLayout: ((TextLayoutResult) -> Unit)? = {},
style: TextStyle? = LocalTextStyle.current
): Unit
用法
直接显示
@Composable
fun TextSample() {
Text(text = "Hello World!")
}
从 res 中读取文字显示
@Composable
fun TextSample() {
Text(text = stringResource(R.string.content))
}
<resources>
<string name="content">你好,世界!</string>
</resources>
参数
color
设置字体颜色
@Composable
fun TextSample() {
Text(text = "Hello World!", color = Color.Red)
}
fontSize
设置文字大小
fontSize 默认是跟随父级文字大小。
接收的是一个 TextUnit,可以设置 SP(像素值) 和 EM(字体值) 单位的值
以下示例是直接使用 TextUnit 创建对象进行赋值,因为这个构造函数还是实验性的,随时都可能有改动或删除,因此需要在函数前增加@OptIn(ExperimentalUnitApi::class)
注解
@OptIn(ExperimentalUnitApi::class)
@Composable
fun TextSample() {
Text(text = "Hello World!", fontSize = TextUnit(16f, TextUnitType.Sp))
}
当然,系统对 Int
、Double
和 Float
三种类型进行了扩展,可以直接按照下面的方式进行使用
import androidx.compose.ui.unit.sp
import androidx.compose.ui.unit.em
@Composable
fun TextSample1() {
Text(text = "Hello World!", fontSize = 16.0.sp))
}
@OptIn(ExperimentalUnitApi::class)
@Composable
fun TextSample2() {
Text(text = "Hello World!", fontSize = 16.em))
}
使用 em 的效果
fontStyle
设置文字样式
- FontStyle.Italic 设置为斜体
- FontStyle.Normal 设置为正常体(默认状态)
@Composable
fun TextSample() {
Text(text = "Hello World!", fontStyle = FontStyle.Italic))
}
fontWeight
设置文字比重
系统预设了很多比重值可以直接使用,例如 FontWeight.Bold
,也可以使用 FontWeight(100)
fontFamily
设置文字字体
同样系统也预设了几个字体供选择使用,例如 FontFamily.SansSerif
。也可以加载 res 下的字体文件
@Composable
fun TextSample() {
val firaSansFamily = FontFamily(
Font(R.font.firasans_light, FontWeight.Light),
Font(R.font.firasans_regular, FontWeight.Normal),
Font(R.font.firasans_italic, FontWeight.Normal, FontStyle.Italic),
Font(R.font.firasans_medium, FontWeight.Medium),
Font(R.font.firasans_bold, FontWeight.Bold)
)
Text(text = "Hello World!", fontFamily = firaSansFamily))
}
letterSpacing
设置字符间距
@Composable
fun TextSample() {
Text(text = "Hello World!", letterSpacing = 15.sp))
}
textDecoration
设置文字装饰
TextDecoration.None
无装饰(默认)TextDecoration.Underline
下划线TextDecoration.LineThrough
删除线
还可以通过TextDecoration.combine()
合并使用多种装饰
@Composable
fun TextSample() {
Text(
text = "Hello World!",
textDecoration = TextDecoration.combine(
listOf(
TextDecoration.LineThrough,
TextDecoration.Underline
)
)
)
}
textAlign
设置文本对齐方式
需要固定宽度,才有效果
TextAlign.Center
TextAlign.End
TextAlign.Justify
效果如图
lineHeight
设置文本行高
@Composable
fun TextSample() {
Text(text = "Hello World!", lineHeight = 15.sp))
}
overflow
设置文本超出时如何显示
TextOverflow.Ellipsis
以省略号显示TextOverflow.Clip
裁剪TextOverflow.Visible
尽可能显示
!!! Tip 目前省略号只能在末尾,无法自定义省略号位置
maxLines
文本显示行数
@Composable
fun TextSample() {
Text(text = "Hello World!", maxLines = 1))
}
style
样式
上面讲到的大部分文字修饰,都可以直接通过 TextStyle 进行修饰,除此之外还多出几个样式
fontFeatureSettings
字体的高级设置,类似 CSS 的font-feature-settings
,可以参考www.w3.org/TR/css-font…background
设置背景颜色shadow
设置阴影textIndent
设置首先缩进
@Composable
fun TextSample() {
Text(
text = "锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦",
modifier = Modifier.width(110.dp),
style = TextStyle(
background = Color.White,
shadow = Shadow(
color = Color.Red,
offset = Offset(5f, 5f),
blurRadius = 10f
),
textIndent = TextIndent(20.sp)
)
)
}
SelectionContainer
文字复制
默认情况下 Text
并不能进行复制等操作,我们需要设置 SelectionContainer
来包装 Text
@Composable
fun TextSample() {
SelectionContainer(
Text(
text = "锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦"
)
)
}
Text 语句中设置不同样式
如果想让一个 Text 语句中有不同的样式,需要使用到 AnnotaedString
AnnotaedString 是一个数据类,包含文本,以及多种样式
@Composable
fun TextSample() {
Text(
buildAnnotatedString {
withStyle(style = SpanStyle(Color.Red)) {
append("锄禾日当午,")
}
withStyle(style = SpanStyle(Color.Green)) {
append("汗滴禾下土。")
}
withStyle(style = SpanStyle(Color.Blue)) {
append("谁知盘中餐,")
}
withStyle(style = SpanStyle(Color.Yellow)) {
append("粒粒皆辛苦")
}
}
)
}
ClickableText
文本点击控件
想要让文本可以接收到点击事件,可以使用 ClickableText
,控件带有一个 onClick
参数,参数回调中还可以知道当前点击字条的 offset 是多少
简单用法
@Composable
fun TextSample() {
ClickableText(
buildAnnotatedString {
withStyle(style = SpanStyle(Color.Red)) {
append("锄禾日当午,")
}
withStyle(style = SpanStyle(Color.Green)) {
append("汗滴禾下土。")
}
withStyle(style = SpanStyle(Color.Blue)) {
append("谁知盘中餐,")
}
withStyle(style = SpanStyle(Color.Yellow)) {
append("粒粒皆辛苦")
}
}, onClick = { offset ->
Log.d("TextSample", "offset:$offset")
}
)
}
高级用法
从上面 设置不同样式 和 文本点击 我们知道了如何在 Text 语句内设置不同的样式,也知道了如何获得点击的文字,那我们是不是可以实现在文本内设置部分文字可以点击呢!
@Composable
fun TextSample() {
val annotatedString = buildAnnotatedString {
append("点击登录代表您知悉和同意")
//往字符串中添加一个注解,直到遇到 pop() 。tag 为注解标识,annotation 为传递内容
pushStringAnnotation("protocol", annotation = "https://docs.bughub.icu/compose")
withStyle(style = SpanStyle(Color.Blue)) {
append("用户协议")
}
pop()
append("和")
pushStringAnnotation("privacy", annotation = "https://randywei.gitee.com")
withStyle(style = SpanStyle(Color.Blue)) {
append("隐私政策")
}
pop()
}
ClickableText(
annotatedString, onClick = { offset ->
//从字符串中查找注解
annotatedString.getStringAnnotations("protocol", start = offset, end = offset)
.firstOrNull()?.let { annotation ->
Log.d("TextSample", "点击了用户协议:${annotation.item}")
}
annotatedString.getStringAnnotations("privacy", start = offset, end = offset)
.firstOrNull()?.let { annotation ->
Log.d("TextSample", "点击了隐私政策:${annotation.item}")
}
}
)
}
Button
属性
@Composable
fun Button(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
elevation: ButtonElevation? = ButtonDefaults.elevation(),
shape: Shape = MaterialTheme.shapes.small,
border: BorderStroke? = null,
colors: ButtonColors = ButtonDefaults.buttonColors(),
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
content: @Composable RowScope.() -> Unit
): Unit
基本用法
@Composable
fun ButtonSample() {
Button(
onClick = {
Log.d("ButtonSample", "click the button")
},
) {
Text(text = "这里有一个按钮")
}
}
参数
enabled
是否启用或禁用
elevation
投影border
边框线
@Composable
fun ButtonSample() {
Button(
onClick = {
Log.d("ButtonSample", "click the button")
},
border = BorderStroke(1.dp,Color.Red)
) {
Text(text = "这里有一个按钮")
}
}
colors
设置颜色,可以设置背景颜色、前景颜色、禁用状态和启动状态下的颜色
@Composable
fun ButtonSample() {
Button(
onClick = {
Log.d("ButtonSample", "click the button")
},
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.Yellow,
contentColor = Color.Green
)
) {
Text(text = "这里有一个按钮")
}
}
contentPadding
内容内间距
TextButton
TextButton
一般是用来显示文字按钮的
@Composable
fun ButtonSample() {
TextButton(
onClick = {
Log.d("ButtonSample", "click the button")
},
) {
Text(text = "TextButton")
}
}
OutlinedButton
用于实现带有边框的按钮
@Composable
fun OutlinedButtonDemo(){
OutlinedButton(onClick = {
println("点击1")
Log.d("OutlinedButtonDemo", "click the button")
},
border = BorderStroke(2.0.dp, Color.Green),
colors = ButtonDefaults.buttonColors(Color.Red)
) {
Text("Outlined Button")
}
}
IconButton
用来显示图标按钮
@Composable
fun ButtonSample() {
IconButton(
onClick = {
Log.d("ButtonSample", "click the button")
},
) {
Icon(imageVector = Icons.Default.Stairs, contentDescription = null)
}
}
Icon
@Composable
fun Icon(
imageVector: ImageVector,//bitmap: ImageBitmap,painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
)
用法一
可以直接引用官方的图标库 ,例如:Icons.Default.AccountBox
@Composable
fun IconSample() {
Icon(imageVector = Icons.Default.AccountBox, contentDescription = null)
}
在官方网站上,我们看到提供的图标库中,有些可能无法正常显示。是因为默认 SDK 中只是包含部分图标,如果需要使用更多图标需要引入扩展库
implementation "androidx.compose.material:material-icons-extended:$compose_version"
用法二
可以使用 drawble 里面的图片
@Composable
fun IconSample() {
Icon(
painter = painterResource(id = R.drawable.ic_android_black_24dp),
contentDescription = null,
tint = Color.Blue
)
}
用法三
可以引用 ImageBitmap
@Composable
fun IconSample() {
var bitmap:ImageBitmap ? = null
with(LocalContext.current){
bitmap = ImageBitmap.imageResource(resources,R.drawable.newbanner4)
}
bitmap?.let { Icon(bitmap = it, contentDescription = null) }
}
参数
tint
设置图标颜色
@Composable
fun IconSample() {
Icon(imageVector = Icons.Default.Deck, contentDescription = null, tint = Color.Red)
}
Image
@Composable
fun Image(
painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null
): Unit
图片跟 Icon 差不多也可以通过三种方式引入图片,本页只展示一种方式
参数
- contentScale 设置图片的伸展方式:ContentScale.Inside、ContentScale.Crop 等
- colorFilter 设置颜色滤镜
@Composable
fun ImageSample() {
Image(
painter = painterResource(id = R.drawable.newbanner4),
contentDescription = null,
contentScale = ContentScale.Inside,
colorFilter = ColorFilter.tint(Color.Red, blendMode = BlendMode.Color)
)
}
TextField
属性
@Composable
fun TextField(
value: String?,
onValueChange: ((String) -> Unit)?,
modifier: Modifier? = Modifier,
enabled: Boolean? = true,
readOnly: Boolean? = false,
textStyle: TextStyle? = LocalTextStyle.current,
label: (@Composable () -> Unit)? = null,
placeholder: (@Composable () -> Unit)? = null,
leadingIcon: (@Composable () -> Unit)? = null,
trailingIcon: (@Composable () -> Unit)? = null,
isError: Boolean? = false,
visualTransformation: VisualTransformation? = VisualTransformation.None,
keyboardOptions: KeyboardOptions? = KeyboardOptions.Default,
keyboardActions: KeyboardActions? = KeyboardActions(),
singleLine: Boolean? = false,
maxLines: Int? = Int.MAX_VALUE,
interactionSource: MutableInteractionSource? = remember { MutableInteractionSource() },
shape: Shape? = MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),
colors: TextFieldColors? = TextFieldDefaults.textFieldColors()
): Unit
参数
- enabled 是否启用禁用,无法聚集,不可编辑,无法复制
- readOnly 是否只读,不可编辑,可复制
- textStyle 设置文本样式
- lable 显示在输入框边框的文本(可选)
- placeHolder 未输入状态下提示文字
- leadingIcon 显示在输入框左侧的图标
- trailingIcon 显示在输入框右侧的图标
- keyboradOptions 键盘类型,如数字键盘
- keyboradActions 功能键事件监听
- singleLine 是否单行显示,如果设置为 true,则忽略maxLines
- maxLines 大于等于1
@Composable
fun TextFieldSample() {
//接收用户输入的值
var name by remember { mutableStateOf("") }
TextField(
value = name,
onValueChange = {
name = it
},
label = {
Text("name")
},
placeholder = {
Text(text = "pls input name")
},
leadingIcon = {
Icon(imageVector = Icons.Default.AccountBox, contentDescription = null)
},
keyboardActions = KeyboardActions(onDone = {
}),
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done,
keyboardType = KeyboardType.Number),
singleLine = true,
)
}
OutlinedTextField
与 TextField 只是样式不同
@Composable
fun TextFieldSample() {
var name by remember { mutableStateOf("") }
OutlinedTextField(value = name, onValueChange = {
name = it
},label = {Text("name")})
}
BasicTextField
最原始的文本输入控件,可以进行深度自定义
@Composable
fun TextFieldSample3() {
var name by remember { mutableStateOf("") }
BasicTextField(value = name, onValueChange = {
name = it
})
}
Slider
属性
@Composable
fun Slider(
value: Float,
onValueChange: (Float) -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
/*@IntRange(from = 0)*/
steps: Int = 0,
onValueChangeFinished: (() -> Unit)? = null,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
colors: SliderColors = SliderDefaults.colors()
) :Unit
参数
- value 当前值
- valueRange 可选值的范围,默认是0f~1f
- steps 步频
@Composable
fun SliderSample() {
var value by remember {
mutableStateOf(0f)
}
Slider(value = value, onValueChange = {
value = it
}, valueRange = 0f..100f, steps = 4)
}
未设置 Step
设置 Steps
RangeSlider
范围选择器
因为还是个实验性的 API,所以需要增加@OptIn(ExperimentalMaterialApi::class)
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun SliderSample2() {
//注意此时值是一个范围
var values by remember {
mutableStateOf(5f..10f)
}
RangeSlider(values = values, onValueChange = {
values = it
}, valueRange = 0f..30f,steps = 3)
}
Checkbox
@Composable
fun Checkbox(
checked: Boolean,
onCheckedChange: ((Boolean) -> Unit)?,
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
colors: CheckboxColors = CheckboxDefaults.colors()
)
- checked 是否选中
- onCheckedChange 选择回调
- enabled 是否启用
@Composable
fun CheckBoxSample() {
//接收选中状态
var checkedList by remember {
mutableStateOf(
listOf(false, false)
)
}
Column {
checkedList.forEachIndexed { i, item ->
Checkbox(checked = item, onCheckedChange = {
checkedList = checkedList.mapIndexed { j, b ->
if (i == j) {
!b
} else {
b
}
}
})
}
}
}
CircularProgressIndicator
属性
@Composable
fun CircularProgressIndicator(
progress: Float?,
modifier: Modifier? = Modifier,
color: Color? = MaterialTheme.colors.primary,
strokeWidth: Dp? = ProgressIndicatorDefaults.StrokeWidth
): Unit
参数
- progress 当前进度0.0~1.0之间,不传递为滚动进度
- color 进度条颜色
- strokeWidth 进度条大小
@Composable
fun CircularProgressIndicatorSample() {
CircularProgressIndicator(
color = Color.Red, strokeWidth = 10.dp
)
}
不传 porgress参数情况
@Composable
fun CircularProgressIndicatorSample1() {
CircularProgressIndicator(progress = 0.5f)
}
LinearProgressIndicator
@Composable
fun LinearProgressIndicatorSample() {
LinearProgressIndicator(color = Color.Red, backgroundColor = Color.Green)
}
@Composable
fun LinearProgressIndicatorSample1() {
LinearProgressIndicator(progress = 0.3f, color = Color.Red, backgroundColor = Color.Green)
}
Switch
属性
@Composable
fun Switch(
checked: Boolean?,
onCheckedChange: ((Boolean) -> Unit)?,
modifier: Modifier? = Modifier,
enabled: Boolean? = true,
interactionSource: MutableInteractionSource? = remember { MutableInteractionSource() },
colors: SwitchColors? = SwitchDefaults.colors()
): Unit
用法
@Composable
fun SwitchSample() {
//声明一个变量来记住选中状态
var switch by remember { mutableStateOf(false) }
Switch(checked = switch, onCheckedChange = {
//当进行切换操作时,更改状态
switch = it
})
}
RadioButton
@Composable
fun RadioButton(
selected: Boolean,
onClick: (() -> Unit)?,
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
colors: RadioButtonColors = RadioButtonDefaults.colors()
):Unit
- checked 是否选中
- onCheckedChange 选择回调
- enabled 是否启用
@Composable
fun RadioButtonSample1() {
var checkedList by remember { mutableStateOf(listOf(false, false)) }
LazyColumn() {
items(checkedList.size) { i ->
RadioButton(selected = checkedList[i], onClick = {
checkedList = checkedList.mapIndexed { j, _ ->
i == j
}
})
}
}
}
Divider
设置分割线
@Composable
fun ColumnSample() {
Column(
modifier = Modifier
.requiredHeight(100.dp)
.background(Color.White),
) {
Text(
text = "First ", modifier = Modifier
.background(Color.Red)
.weight(0.7f,fill=false)
)
Divider()
Text("Second", modifier = Modifier
.background(Color.Green)
.weight(0.3f))
}
}
Spacer
空白区域,通过 modifier 设置空白区域的大小
@Composable
fun SpacerSample() {
Column(modifier = Modifier.background(Color.White)) {
Row(modifier = Modifier.size(100.dp)) {
Text("First", modifier = Modifier.background(Color.Red))
Spacer(modifier = Modifier.weight(1f))
Text("Second", modifier = Modifier.background(Color.Green))
}
Divider()
Text("Column Item 0", modifier = Modifier.background(Color.Red))
Spacer(modifier = Modifier.weight(1f))
Text("Column Item 1", modifier = Modifier.background(Color.Green))
}
}