Jetack Compose(2)组件—基础按钮(构造函数属性详解,点击事件,启用协程模拟文件提交,点击切换背景图).........分段按钮(单/多选)以及选中图标/文字样式修改等详细教程

一、按钮布局以及按钮点击事件

按钮是基本组件,可让用户触发已定义的操作。Jetpack Compose 提供了多种预定义的按钮样式

1.1、5种按钮样式

    @Composable
    fun ButtonExample() {
        Column(
        //让当前组件填充父容器的最大可用宽高,类似于XML 布局中的match_parent 或 fill_parent
        modifier = Modifier.fillMaxSize(),
         //按钮在布局中居中显示
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally)
        {
            //填充按钮,默认情况下,它会以纯色填充
            Button(onClick = { Log.d("MyButtonActivity", "Button: ") }) {
                Text("Button")
            }
            // 填充色调按钮,默认情况下,它会填充色调颜色
            FilledTonalButton(onClick = { Log.d("MyButtonActivity", "TonalButton: ") }) {
                Text("TonalButton")
            }
            //轮廓按钮,默认情况下,它会显示轮廓
            OutlinedButton(onClick = { Log.d("MyButtonActivity", "OutlinedButton: ") }) {
                Text("OutlinedButton")
            }
            //凸起按钮,它是一个包含阴影的填充按钮
            ElevatedButton(onClick = { Log.d("MyButtonActivity", "ElevatedButton: ") }) {
                Text("ElevatedButton")
            }
            //文本按钮,在按之前,它仅显示为文字。默认情况下,它没有实心填充或轮廓
            TextButton(onClick = { Log.d("MyButtonActivity", "TextButton: ") }) {
                Text("TextButton")
            }
        }

    }

效果如下:

1.2、以Button按钮为例介绍其构造函数常用属性

     //创建了一个 Button 组件
        Button(
            //点击按钮执行事件
            onClick = { /* 点击处理逻辑 */ },
            //修饰符,用于调整布局、大小等
            modifier = Modifier.padding(32.dp),
            // 控制是否可点击
            enabled = true,
            //阴影效果
            elevation = ButtonDefaults.buttonElevation(
                defaultElevation = 8.dp,
                pressedElevation = 4.dp,
                disabledElevation = 0.dp
            ),
            // 按钮形状,圆角40
            shape = RoundedCornerShape(40.dp),
            // 按钮边框样式
            border = BorderStroke(3.dp, Color.Blue),
            // 设置按钮点击/禁用时颜色变化效果:填充色 文字颜色
//                colors = ButtonDefaults.buttonColors
//                    (containerColor = Color.Blue,  contentColor = Color.White,
//                    disabledContainerColor = Color.Gray, disabledContentColor = Color.White),
            // 内容内边距,相当于xml的padding
            contentPadding = PaddingValues(horizontal = 20.dp, vertical = 8.dp)
        )
        //大括号 {} 内的内容是 Button 组件的 content 参数,它定义了按钮内部显示的内容和布局
        //当函数的最后一个参数是 lambda 时,可以移到括号外面
        //这些组件默认会按照 水平方向(Row) 自动排列
        {
            Icon(Icons.Filled.Favorite, contentDescription = null)
            Spacer(Modifier.size(16.dp))
            Text( "提交")
        }

预览效果如下:

1.3、按钮点击事件

        应用:实现点击按钮模拟提交文件,延迟2秒后按钮恢复正常 。

       在这个案例中,我们不需要设置太多属性

 @Composable
    fun ButtonExample() {
        //使用 remember 和 mutableStateOf 创建了一个可观察的状态变量 isEnabled管理 UI 状态
        //状态变化自动触发 UI 重组
        var isEnabled: Boolean by remember { mutableStateOf(true) }

        //获取一个与当前组合生命周期绑定的协程作用域,使用 rememberCoroutineScope 安全地启动协程
        //delay函数需在协程中执行
        val coroutineScope = rememberCoroutineScope()

        //点击按钮模拟文件提交功能
        fun myButtonClick() {
            isEnabled = false  // 点击后立即禁用点击功能
            coroutineScope.launch {
                delay(2000) // 延迟2秒
                isEnabled = true // 恢复原始状态
            }
        }
        //创建了一个 Button 组件
        Button(
            //点击按钮执行事件
            onClick = { myButtonClick() },
            // 控制是否可点击
            enabled = isEnabled,
            // 设置按钮点击/禁用时颜色变化效果:填充色 文字颜色
            colors = ButtonDefaults.buttonColors
                (containerColor = Color.Blue,  contentColor = Color.White,
                disabledContainerColor = Color.Gray, disabledContentColor = Color.White),
        ) { Text(if (isEnabled) "提交" else "处理中...") }
    }

运行效果:点击后置灰2秒钟,后又恢复正常状态

1.4、按钮点击切换背景图

    在 Jetpack Compose 中,标准 Button 组件没有直接提供设置背景图片的属性,这是设计上的有意为之——Material Design 规范中的按钮通常使用纯色或渐变背景,而不是图片背景。

  如果想要实现点击按钮切换背景图,可以使用 Box 容器 + Image 模拟按钮或者通过 Button 的 content 参数嵌入图片,下面我们用第二种方法实现点击切换背景图。

    @Composable
    fun ButtonExample() {
        //使用 remember 和 mutableStateOf 创建了一个可观察的状态变量 isSelect管理 UI 状态
        //状态变化自动触发 UI 重组
        var isSelect: Boolean by remember { mutableStateOf(true) }
        //点击按钮切换背景图
        fun myButtonClick() {
            isSelect = !isSelect  
        }
        //创建了一个 Button 组件
        Button(
            //点击按钮执行事件
            onClick = { myButtonClick() },
            // 透明背景
            colors = ButtonDefaults.buttonColors(containerColor = Color.Transparent)
        ) {
            Image(
                painter = painterResource( if (isSelect) R.mipmap.clickblue else R.mipmap.clickgray),
                contentDescription = null,
                contentScale = ContentScale.Crop,
                modifier = Modifier.fillMaxWidth()
            )
        }
    }

二、分段按钮

 2.1、单选分段按钮

    @OptIn(ExperimentalMaterial3Api::class)
    @Composable
    fun SingleChoiceSegmentedButton() {
        //使用 remember 和 mutableStateOf初始化 selectedIndex 变量,以跟踪所选按钮的索引
        //状态变化自动触发 UI 重组
        var selectedIndex by remember { mutableIntStateOf(0) }

        //定义表示按钮标签的 options 列表
        val options = listOf("日", "周", "月")
        //SingleChoiceSegmentedButtonRow 仅允许选择一个按钮
        SingleChoiceSegmentedButtonRow {
            //在 forEachIndexed 循环内,为每个选项创建一个 SegmentedButton
            options.forEachIndexed { index, label ->
                SegmentedButton(
                    //定义按钮的形状
                    shape = SegmentedButtonDefaults.itemShape(
                        index = index,
                        count = options.size
                    ),
                    //点击按钮更新索引 selectedIndex
                    onClick = { selectedIndex = index },
                    //设置选中/未选中的背景以及内容颜色
//                    colors = SegmentedButtonDefaults.colors(
//                        //ContainerColor分段按钮的背景颜色
//                        activeContainerColor = Color.Red,//选中
//                        inactiveContainerColor = Color.LightGray,//未选中
//                        //ContentColor:选中状态下所有内容(包括文本和图标)的颜色
//                        activeContentColor=Color.White,//选中
//                        inactiveContentColor = Color.Black//未选中
//                    ),
                   // icon = {},//这样设置,选中的默认图标就会消失
                   
                    icon ={
                            if (selectedIndex == index)
                            {
                              //从material系统库中设置自己想要的图标
                                Icon(
                                    imageVector = Icons.Default.Star,
                                    contentDescription = "选中",
                                    tint = Color.Yellow
                                )
                            }
                          },
                    //根据 selectedIndex 设置按钮的选择状态
                    selected = index == selectedIndex,
                    //使用 Text 可组合函数显示按钮标签
                    label = { Text(label) }
                )
            }
        }

    }

效果如下(从库中选择自己想要的图标样式)

库中包含的图标有以下样式

2.1.1、设置美工提供的图标样式

  单选分段按钮如果想要设置美工提供的图标样式,我们可以用Image,不用Icon

     //设置美工设计师提供的图标用Image
                                Image(
                                    painter = painterResource(id = R.drawable.icon_selected),
                                    contentDescription = "已选中",
                                    modifier = Modifier.size(24.dp)
                                )

2.2、多选分段按钮

此示例展示了如何创建带有图标的多选分段按钮,让用户可以选择多个选项,多选分段按钮样式设置与单选相似。

 //可让用户选择 2 到 5 个项目
    @OptIn(ExperimentalMaterial3Api::class)
    @Composable
    fun MultiChoiceSegmentedButton() {
        //使用 remember 和 mutableStateOf初始化 selectedOptions 变量,以跟踪每个按钮的选中状态
        //默认三个都不被选中
        val selectedOptions = remember { mutableStateListOf(false, false, false) }
        //定义表示按钮标签的 options 列表
        val options = listOf("日", "周", "月")
        //MultiChoiceSegmentedButtonRow 允许选择多个按钮
        MultiChoiceSegmentedButtonRow {
            //在 forEachIndexed 循环内,为每个选项创建一个 SegmentedButton
            options.forEachIndexed { index, label ->
                SegmentedButton(
                    //定义按钮的形状
                    shape = SegmentedButtonDefaults.itemShape(
                        index = index,
                        count = options.size
                    ),
                    //设置选中/未选中的背景以及内容颜色
//                    colors = SegmentedButtonDefaults.colors(
//                        //ContainerColor分段按钮的背景颜色
//                        activeContainerColor = Color.Red,//选中
//                        inactiveContainerColor = Color.LightGray,//未选中
//                        //ContentColor:选中状态下所有内容(包括文本和图标)的颜色
//                        activeContentColor=Color.White,//选中
//                        inactiveContentColor = Color.Black//未选中
//                    ),
                    //checked 根据 selectedOptions 中的相应值设置按钮的选中状态
                    checked = selectedOptions[index],
                    //点击按钮时,onCheckedChange 会切换 selectedOptions 中相应项的选择状
                    onCheckedChange = {
                        selectedOptions[index] = !selectedOptions[index]
                    },
                    // icon = {},//这样设置,选中的默认图标就会消失
                    icon ={
                        if (selectedOptions[index]) {
                            //从material系统库中设置自己想要的图标
//                            Icon(
//                                imageVector = Icons.Default.Star,
//                                contentDescription = "选中",
//                                tint = Color.Yellow
//                            )
                            //设置美工设计师提供的图标用Image
                            Image(
                                painter = painterResource(id = R.drawable.icon_selected),
                                contentDescription = "已选中",
                                modifier = Modifier.size(24.dp)
                            )
                        }
                    },
                    //使用 Text 可组合函数显示按钮标签
                    label = { Text(label) }
                )
            }
        }
    }

多选按钮效果如下

2.3、单选与多选按钮代码区别对比

2.4、分段按钮的label标签不用text,改用图标icon

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗的菇凉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值