按钮还是很常见也是非常重要的。在Compose中按钮的名字和Android View中的名字一样都叫做Button,我们先看看它的创建:
// 按钮的用法
Column {
Button(
modifier = Modifier.height(50.dp).width(150.dp), // 大小
onClick = {
// 点击事件
}) {
Text(text = "按钮") // 按钮文案,对应content
}
}
复制代码
代码中我们创建了Button,并设置了其大小、文案和点击事件,效果如上。 我们再来看下Button类的源码:
@OptIn(ExperimentalMaterialApi::class)
@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 // 内容
) {
// 省略...
}
复制代码
Button的参数还是比较少的,有些参数和之前的控件重复的就不说了,我们来看几个陌生没见过的参数。
onclick
onclick参数是一个block函数,不允许为空,按钮如果没有点击事件,就没有任何意义了。
enabled
是控制按钮的启用状态,在Android View中已经很常见了,为true的时候按钮可以正常点击,否则不可点击。
interactionSource
表示按钮的交互流,其类型为MutableInteractionSource,如果要观察交互并自定义按钮在不同交互中的外观、行为,可以创建并传递按钮记住的MutableInteractionSource。类似Android View中的自定义的selector.xml
elevation
按钮不同状态下的高度,类型为ButtonElevation,还可以控制按钮下方阴影大小,看下它的源码:
@Stable
interface ButtonElevation {
/**
* 按钮中使用的标准高度,具体取决于enabled和interactionSource
*
* @param 按钮是否可点击
* @param 按钮的InteractionSource
*/
@Composable
fun elevation(enabled: Boolean, interactionSource: InteractionSource): State<Dp>
}
复制代码
它是一个接口,如果想修改按钮的高度,就需要实现该接口方法去修改。elevation的默认值是ButtonDefaults.elevation(),它的实现如下:
@Composable
fun elevation(
defaultElevation: Dp = 2.dp, // 启用按钮时的默认高度
pressedElevation: Dp = 8.dp, // 启用并按下按钮时的高度
disabledElevation: Dp = 0.dp // 禁用按钮时的高度
): ButtonElevation {
return remember(defaultElevation, pressedElevation, disabledElevation) {
DefaultButtonElevation(
defaultElevation = defaultElevation,
pressedElevation = pressedElevation,
disabledElevation = disabledElevation
)
}
}
复制代码
DefaultButtonElevation实现ButtonElevation接口的代码了,返回的是ButtonElevation,而且elevation接收了一些参数,当你要使用elevation时,也可以使用ButtonDefaults.elevation,只需要配置具体情况的高度即可,来看一个例子:
Column {
Button(
modifier = Modifier
.height(100.dp)
.width(250.dp), // 大小
onClick = {
// 点击事件
},
elevation = ButtonDefaults.elevation(3.dp, 10.dp, 0.dp)
) {
Text(text = "按钮") // 按钮文案,对应content
}
}
复制代码
border
border参数类型是BorderStroke,默认值为null,可以用来绘制按钮的边框:
Column {
Button(
modifier = Modifier
.height(100.dp)
.width(250.dp), // 大小
onClick = {
// 点击事件
},
elevation = ButtonDefaults.elevation(3.dp, 10.dp, 0.dp),
border = BorderStroke(6.dp, Color.Yellow)
) {
Text(text = "按钮") // 按钮文案,对应content
}
}
复制代码
我们可以看到6dp的边框。
shape
shape之前有学习过,这里不多说了,shape在按钮中用处很大,在Android View中如果想给一个Button加shape,我们都会自定义一个shape.xml;在Compose中Button不需要这样,我们看看怎么添加:
Column {
Button(
modifier = Modifier
.height(100.dp)
.width(250.dp), // 大小
onClick = {
// 点击事件
},
elevation = ButtonDefaults.elevation(3.dp, 10.dp, 0.dp),
border = BorderStroke(6.dp, Color.Yellow),
shape = RoundedCornerShape(20.dp) // 添加的shape
) {
Text(text = "按钮") // 按钮文案,对应content
}
}
复制代码
我们看到是20dp圆角大小形状的按钮。是不是很简单。
colors
colors用来设置按钮在不同状态下的颜色,类型是ButtonColors,它也是一个接口。
@Stable
interface ButtonColors {
/**
* 背景颜色
*/
@Composable
fun backgroundColor(enabled: Boolean): State<Color>
/**
* 内容颜色
*/
@Composable
fun contentColor(enabled: Boolean): State<Color>
}
复制代码
Button中colors默认是ButtonDefaults.buttonColors(),我们来看看buttonColors。
@Composable
fun buttonColors(
backgroundColor: Color = MaterialTheme.colors.primary, // 背景颜色
contentColor: Color = contentColorFor(backgroundColor), // 内容颜色
disabledBackgroundColor: Color = MaterialTheme.colors.onSurface.copy(alpha = 0.12f)
.compositeOver(MaterialTheme.colors.surface), // 未启用时的背景色
disabledContentColor: Color = MaterialTheme.colors.onSurface
.copy(alpha = ContentAlpha.disabled) // 未启用时内容颜色
): ButtonColors = DefaultButtonColors(
backgroundColor = backgroundColor,
contentColor = contentColor,
disabledBackgroundColor = disabledBackgroundColor,
disabledContentColor = disabledContentColor
)
复制代码
这里和elevation一样,我们使用时用系统默认的方法即可,只需要传入需要修改的值,来看看colors怎么用:
Column {
val context = LocalContext.current
Button(
modifier = Modifier
.height(100.dp)
.width(250.dp), // 大小
onClick = {
// 点击事件
Toast.makeText(context, "点击按钮", Toast.LENGTH_LONG).show()
},
elevation = ButtonDefaults.elevation(3.dp, 10.dp, 0.dp),
border = BorderStroke(6.dp, Color.Yellow),
shape = RoundedCornerShape(20.dp),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.Red,
contentColor = Color.Green,
disabledBackgroundColor = Color.Yellow,
disabledContentColor = Color.Magenta
)
) {
Text(text = "按钮") // 按钮文案,对应content
}
}
复制代码
contentPadding
内边距,和Android View中的padding一样。其类型为PaddingValues,它是一个接口。Button中contentPadding的默认值是ButtonDefaults.ContentPadding,
object ButtonDefaults {
private val ButtonHorizontalPadding = 16.dp
private val ButtonVerticalPadding = 8.dp
/**
* The default content padding used by [Button]
*/
val ContentPadding = PaddingValues(
start = ButtonHorizontalPadding, // 左
top = ButtonVerticalPadding, // 上
end = ButtonHorizontalPadding, // 右
bottom = ButtonVerticalPadding // 下
)
// 省略
}
复制代码
都有默认值,左右为16dp, 上下为8dp,我们要修改的话,直接使用PaddingValues方法设置对应的内边距即可。Compose提供了几个方法供我们使用:
@Stable
fun PaddingValues(
start: Dp = 0.dp,
top: Dp = 0.dp,
end: Dp = 0.dp,
bottom: Dp = 0.dp
): PaddingValues = PaddingValuesImpl(start, top, end, bottom)
复制代码
使用上:
// 按钮的用法
Column {
val context = LocalContext.current
Button(
modifier = Modifier
.height(100.dp)
.width(250.dp), // 大小
onClick = {
// 点击事件
Toast.makeText(context, "点击按钮", Toast.LENGTH_LONG).show()
},
elevation = ButtonDefaults.elevation(3.dp, 10.dp, 0.dp),
border = BorderStroke(6.dp, Color.Yellow),
shape = RoundedCornerShape(20.dp),
colors = ButtonDefaults.buttonColors(
backgroundColor = Color.Red,
contentColor = Color.Green,
disabledBackgroundColor = Color.Yellow,
disabledContentColor = Color.Magenta
),
contentPadding = PaddingValues(8.dp)
) {
Text(text = "按钮") // 按钮文案,对应content
}
}
复制代码
其实总体来说,用法还是很简单的,其他感兴趣的用法可以自己试着去用下。相关代码已提交到github github.com/Licarey/com…