Jetpack Compose(五)-按钮组件

一、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效果

参考了以下内容

Jetpack Compose博物馆

实体书 Jetpack Compose从入门到实战

相关推荐
alexhilton2 小时前
Room Fts4:全文搜索替代 SQL LIKE
android·kotlin·android jetpack
hai_android7 小时前
把 Android App 打包成系统应用(System App)
android·kotlin·android jetpack
JMchen7 小时前
【Jetpack 内核实战 01】开篇:Jetpack 组件全家桶核心逻辑与专栏完整规划
android·kotlin·android jetpack
骑着蜗牛撵大象3279 小时前
Linux 进程间通信之管道:从 pipe() 的内核语义到 FIFO 落地排错
android·java·linux·系统编程·fifo·管道·进程间通信
hunterandroid10 小时前
Retrofit 网络请求的异常处理与重试策略实战
android
sejinan10 小时前
极致轻量与秒级起播:NativeWasmTv 开源硬核技术解析与升级版体验
android·开源·webview·tv
小羊没烦恼!10 小时前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp
mmsx11 小时前
Android 静默失败实录:五个没有日志的线上事故
android·kotlin
hai_android11 小时前
从零实现一个支持跨进程(IPC)的自定义 Toast
android·kotlin·android jetpack
龙腾-虎跃12 小时前
基于 SIP 协议的自研电话终端:FreeSWITCH 语音与视频通信实战
android·音视频·freeswitch·sip协议终端·wertc