一、Button按钮
(1)先看下Button
的参数:
kotlin
@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是必填项,这是其最重要的功能,通过回调响应用户点击事件。最后一个参数content
也是一个必填项,也是其最重要的功能之一。Compose
的Button
默认没有任何UI。仅仅是一个响应onClick
的容器,它的UI需要在content
中通过其他组件来实现。
Button
的onClick
在底层是通过覆盖Modifier.clickable
实现的,所以不要为Button
设置Modifier.clickable
,即使设置了,也会因为被onClick
覆盖而没有任何效果。
(2)创建一个显示文字的Button
,代码如下:
kotlin
@Composable
fun Greeting() {
Button(onClick = {
showToast("点击了按钮")
}) {
Text(text = "确定")
}
}
content
提供了RowScope
的作用域,所以当我们想在文字前面水平摆放一个Icon
时,只需要在content
中顺序书写即可:
kotlin
@Composable
fun Greeting() {
Button(onClick = {
showToast("点击了按钮")
}) {
Icon(imageVector = Icons.Filled.Done, contentDescription = null)
Text(text = "确定")
}
}
UI效果
(3)Button
的参数interactionSource
。 Button
有一个参数interactionSource
,它是一个可以监听组件状态的事件源,通过它我们可以根据组件状态设置不同的样式,比如按钮按下时什么效果,正常时什么效果,类似传统视图中的Selector
。interactionSource
通过以下方法获取当前组件状态:
interactionSource.collectIsPressedAsState()
判断是否按下状态。interactionSource.collectIsFocusedAsState()
判断是否获取焦点的状态。interactionSource.collectIsDraggedAsState()
判断是否拖动。
来看下面的例子,通常状态下按钮背景色为灰色,当处于按下状态时,背景色变为黑色:
kotlin
@Composable
fun Greeting() {
val interactionSource = remember { MutableInteractionSource() }
val pressState = interactionSource.collectIsPressedAsState()
val backgroundColor = if (pressState.value) Color.Black else Color.Gray
Button(
onClick = {},
interactionSource = interactionSource,
colors = ButtonDefaults.buttonColors(backgroundColor = backgroundColor)
) {
Text(text = "确定", color = Color.White)
}
}
UI效果
在Jetpack Compose博物馆中有一种写法可以借鉴:
①创建 Data class
来记录不同状态下按钮的样式
kotlin
data class ButtonState(var text: String, var textColor: Color, var buttonColor: Color)
②使用 MutableInteractionSource()
获取状态,根据不同状态创建样式,代码如下:
kotlin
@Composable
fun Greeting() {
// 获取按钮的状态
val interactionState = remember { MutableInteractionSource() }
// 使用 Kotlin 的解构方法
val (text, textColor, buttonColor) = when {
interactionState.collectIsPressedAsState().value -> ButtonState("Just Pressed", Color.Red, Color.Black)
else -> ButtonState( "Just Button", Color.White, Color.Red)
}
Button(
onClick = { /*TODO*/ },
interactionSource = interactionState,
elevation = null,
shape = RoundedCornerShape(50),
colors = ButtonDefaults.buttonColors(
backgroundColor = buttonColor, //buttonColor
),
modifier = Modifier.width(IntrinsicSize.Min).height(IntrinsicSize.Min)
) {
Text(
text = text, color = textColor //text,textColor
)
}
}
二、IconButton图标按钮
见上一篇中的IconButton
三、FloatingActionButton(FAB)悬浮按钮
具体参数如下:
kotlin
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun FloatingActionButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
shape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
backgroundColor: Color = MaterialTheme.colors.secondary,
contentColor: Color = contentColorFor(backgroundColor),
elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
content: @Composable () -> Unit
) {...}
下面是一个简单的例子
kotlin
@Composable
fun Greeting() {
val isClick = remember {
mutableStateOf(false)
}
//修改图标
val imageVector = if (isClick.value) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder
FloatingActionButton(
onClick = { isClick.value = !isClick.value },
backgroundColor = Color.White,
contentColor = Color.Red
) {
Icon(imageVector = imageVector, contentDescription = null)
}
}
UI效果
除了普通的FAB之外,Compose也提供了带有文字扩展的FAB,即ExtendedFloatingActionButton组件,源码如下:
kotlin
@Composable
fun ExtendedFloatingActionButton(
text: @Composable () -> Unit,
onClick: () -> Unit,
modifier: Modifier = Modifier,
icon: @Composable (() -> Unit)? = null,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
shape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
backgroundColor: Color = MaterialTheme.colors.secondary,
contentColor: Color = contentColorFor(backgroundColor),
elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation()
) {...}
下面是一个简单的例子:
kotlin
@Composable
fun Greeting() {
ExtendedFloatingActionButton(
text = { Text(text = "喜欢") },
onClick = { },
icon = { Icon(imageVector = Icons.Filled.Favorite, contentDescription = null) },
contentColor = Color.Red
)
}
UI效果