Flutter之SegmentedButton

本文介绍了在Flutter项目中实现分段选项卡UI的方法,包括使用CupertinoSegmentedControl和SegmentedButton。示例代码展示了如何配置和控制选中状态,并提供了自定义样式的提示。文章还提到了使用Getx进行状态管理。
摘要由CSDN通过智能技术生成

项目的设计图出现分段选项卡UI,如图:
在这里插入图片描述

作为一名iOS开发工程师,看见图第一瞬间就想起来UISegmentedControl这个控件,用法其实也比较简单,但是当前项目是用Flutter写的跨平台项目,研究了一下,Flutter里面也有相应的Widget,记录一下使用过程😄

1.CupertinoSegmentedControl
这个是iOS版的segmented控件,基本是差不多的,使用方法也比较简单:

final Map<T, Widget> children:其中一个children是一个字典,和不是常规的数组形式,以key、value对应,key可以任意,value为Widget

Obx(() {
                return CupertinoSegmentedControl(
                  //子标签
                  children: const  {
                    0: Text("价格"),
                    1: Text("成交量"),
                    2: Text("成交额"),
                  },
                  //当前选中的索引
                  groupValue: logic.segmentIndex.value,
                  //点击回调
                  onValueChanged: (int index) {
                    print("当前选中 $index");
                    logic.segmentIndex.value = index;
                  },
                  //选中的背景颜色
                  selectedColor: ColorsUtil.hexToColor("#52596D"),
                  //未选中的背景颜色
                  unselectedColor: Colors.white,
                  //边框颜色
                  borderColor: ColorsUtil.hexToColor("#52596D"),
                  //按下的颜色
                  pressedColor: ColorsUtil.hexToColor("#52596D").withOpacity(0.4),
                );
              })

我这里是使用的Getx来处理的,更改选中,也可以 setState((){})也一样的,看个人习惯就好。
效果:
在这里插入图片描述
2.SegmentedButton

可以先定义一个类型,来具体区分点击和不同需求处理,当然,也可以直接用int来代替,都可以的,都比较容易区分,我这里定义了一个type,仿照的官方文档形式
enum SegmentType {
price, //价格
turnover, //成交量
volume, //成交额
marketValue, //市值
}
这个Widget有固定的高度,过高,不太符合我项目具体需求,我就尝试从外部固定了widget的高度,也基本能实现,具体情况仅供参考哈 😋

Obx(() =>
                  Padding(
                    padding:
                    const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
                    child: SizedBox(
                      height: 35,
                      child: SegmentedButton<SegmentType>(
                        segments: const [
                          ButtonSegment<SegmentType>(
                            value: SegmentType.price,
                            label: SizedBox(height: 35, child: Text("价格")),
                            //icon: Icon(Icons.add),
                            enabled: true,
                          ),
                          ButtonSegment<SegmentType>(
                            value: SegmentType.turnover,
                            label: SizedBox(height: 35, child: Text("成交量")),
                            // icon: Icon(Icons.safety_check),
                          ),
                          ButtonSegment<SegmentType>(
                            value: SegmentType.volume,
                            label: SizedBox(height: 35, child: Text("成交额")),
                            // icon: Icon(Icons.safety_check),
                          ),
                        ],
                        style: ButtonStyle(
                          side: MaterialStateProperty.all(
                              const BorderSide(color: Colors.black, width: 1)),
                          shape: MaterialStateProperty.all(
                              const RoundedRectangleBorder(
                                borderRadius: BorderRadius.all(
                                    Radius.circular(3)),
                              )),
                          textStyle: MaterialStateProperty.all(
                              const TextStyle(fontSize: 13)),
                          backgroundColor: MaterialStateProperty.resolveWith<
                              Color>(
                                (Set<MaterialState> states) {
                              if (states.contains(MaterialState.selected)) {
                                return ColorsUtil.hexToColor("#52596D");
                              }
                              return Colors.white;
                            },
                          ),
                        ),
                        showSelectedIcon: false,
                        // 是否允许多选
                        // multiSelectionEnabled: false,
                        // 可选空
                        // emptySelectionAllowed: false,
                        selected: {logic.selectSegmentType.value},
                        onSelectionChanged: (Set<SegmentType> segmentType) {
                          print("点击的是:$segmentType");
                          logic.selectSegmentType.value = segmentType.first;
                        },
                      ),
                    ),
                  )),

一些自定义样式,都基本上用ButtonStyle来处理实现的,可根据自己设计图UI来修改调整哈~

我这里是使用的Getx来处理的,更改选中,也可以 setState((){})也一样的,看个人习惯就好。
效果:
在这里插入图片描述

长风破浪会有时,直挂云帆济沧海~一起加油!!! 😄

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter中,ButtonStyle是一个用于定制按钮样式的类。通过使用ButtonStyle,我们可以创建自定义的按钮样式,以满足我们的需求。ButtonStyle可以与内置的button组件(如ElevatedButton)配合使用,通过设置ButtonStyle属性来改变按钮的外观和交互效果。\[1\] 在Flutter 2.0发布时引入了ButtonStyle和MaterialStateProperty。在Flutter 1中,我们可以通过设置textColor、backgroundColor等参数来配置按钮的样式。但是在Flutter 2中,这些参数被废弃了,取而代之的是ButtonStyle。ButtonStyle可以通过MaterialStateProperty来支持不同平台下的交互状态展示。\[3\] 通过ButtonStyle,我们可以使用MaterialStateProperty来定义按钮在不同状态下的样式,例如按下、禁用、悬停等。我们还可以使用StatefulButtonButtonBar、自定义按钮形状和自定义按钮效果等高级用法来进一步定制按钮的外观和交互效果。\[2\] 总之,ButtonStyle是Flutter中用于定制按钮样式的重要类,通过合理运用ButtonStyle和相关属性,我们可以快速开发出符合需求的按钮样式,并为用户提供更好的用户体验。 #### 引用[.reference_title] - *1* [【Flutter】关于Button 的那些知识ElevatedButton等,以及Buttonstyle](https://blog.csdn.net/weixin_43444734/article/details/128582374)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Flutter 中的 ButtonStyle 和 MaterialStateProperty:深入了解](https://blog.csdn.net/chuxia120715/article/details/129673592)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值