flutter开发实战-ListWheelScrollView与自定义TimePicker时间选择器

news/2024/7/7 18:27:28 标签: flutter, 1024程序员节

flutter开发实战-ListWheelScrollView与自定义TimePicker

最近在使用时间选择器的时候,需要自定义一个TimePicker效果,当然这里就使用了ListWheelScrollView。ListWheelScrollView与ListView类似,但ListWheelScrollView渲染效果类似滚筒效果。
在这里插入图片描述

一、ListWheelScrollView

基本用法

  ListWheelScrollView({
    super.key,
    this.controller,
    this.physics,
    this.diameterRatio = RenderListWheelViewport.defaultDiameterRatio,
    this.perspective = RenderListWheelViewport.defaultPerspective,
    this.offAxisFraction = 0.0,
    this.useMagnifier = false,
    this.magnification = 1.0,
    this.overAndUnderCenterOpacity = 1.0,
    required this.itemExtent,
    this.squeeze = 1.0,
    this.onSelectedItemChanged,
    this.renderChildrenOutsideViewport = false,
    this.clipBehavior = Clip.hardEdge,
    this.restorationId,
    this.scrollBehavior,
    required List<Widget> children,
  })
    

ListWheelScrollView的一些属性,如children是子控件

  • children是子控件,
  • itemExtent是每个item的高度
  • magnification是圆筒直径和主轴渲染窗口的尺寸比,默认值是2
  • perspective是圆柱投影试图,为0表示从无限远处看,1表示从无限近处看。默认值0.003
  • offAxisFraction表示圆筒水平偏移中心的程度
  • magnification与useMagnifier放大镜,分辨设置放大镜与放大倍率。
  • squeeze表示圆筒上子控件数量与在同等大小的平面上的子控件的数量之比。

看下ListWheelScrollView基本用法

Container(
          height: 250,
         child: ListWheelScrollView(
            itemExtent: 50,
            children: [
              Container(
                color: Colors.red,
              ),
              Container(
                color: Colors.orangeAccent,
              ),
              Container(
                color: Colors.yellow,
              ),
              Container(
                color: Colors.green,
              ),
              Container(
                color: Colors.teal,
              ),
              Container(
                color: Colors.blue,
              ),
              Container(
                color: Colors.purple,
              ),
            ],
          ),
        )
    

效果图如下
在这里插入图片描述
如果将diameterRatio调整为1的

效果图如下

在这里插入图片描述

其他属性的效果可以逐个尝试一下。

如果使用的数据比较多时候,可以使用userDelegate方式, 使用ListWheelChildBuilderDelegate来指定builder与childCount.

 Container(
          height: 350,
          child: ListWheelScrollView.useDelegate(
            itemExtent: 50,
            diameterRatio: 2,
            childDelegate:
                ListWheelChildBuilderDelegate(builder: (context, index) {
              return Container(
                color: Colors.lightBlue,
                alignment: Alignment.center,
                child: Text("$index",
                    style: TextStyle(color: Colors.white, shadows: [
                      Shadow(
                          color: Colors.black,
                          offset: Offset(.5, .5),
                          blurRadius: 2)
                    ])),
              );
            }, childCount: 100),
          ),
        );
    

效果图如下

在这里插入图片描述
当然还有一个ListWheelChildLoopingListDelegate可以表现出来循环滚动的效果

final List dataList = [
    "第1行",
    "第2行",
    "第3行",
    "第4行",
    "第5行",
    "第6行",
    "第7行",
    "第8行",
    "第9行",
    "第10行",
  ];

  Widget buildChildItem(String text) {
    return Container(
      color: Colors.lightBlue,
      alignment: Alignment.center,
      child: Text("$text",
          style: TextStyle(color: Colors.white, shadows: [
            Shadow(
                color: Colors.black,
                offset: Offset(.5, .5),
                blurRadius: 2)
          ])),
    );
  }

  void testListWheelScrollViewDelegate(BuildContext context) {
    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      builder: (ctx) {
        return Container(
          height: 350,
          child: ListWheelScrollView.useDelegate(
            itemExtent: 50,
            diameterRatio: 2,
            childDelegate: ListWheelChildLoopingListDelegate(children: dataList.map((e) => buildChildItem(e)).toList())),
        );
      },
    );
  }
    

效果图如下

在这里插入图片描述

二、自定义TimePicker

自定义TimePicker使用ListWheelScrollView
自定义TimePicker有小时和分钟,左边显示小时,右边显示分钟。点击确定确认选择的时间,时间格式为10:20
onSelectedItemChanged来确认选择的item
在这里插入图片描述
完整代码如下


class CustomTimePicker extends StatefulWidget {
  const CustomTimePicker({
    super.key,
    this.width,
    this.height,
  });

  final double? width;
  final double? height;

  @override
  State<CustomTimePicker> createState() => _CustomTimePickerState();
}

class _CustomTimePickerState extends State<CustomTimePicker> {
  List<String> hourData = [];
  List<String> minuteData = [];

  String selectedHour = "";
  String selectedminute = "";

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    for (int i = 0; i < 24; i++) {
      String hour = i.toString();
      if (i < 10) {
        hour = "0" + i.toString();
      }
      hourData.add(hour);
    }

    for (int i = 0; i < 60; i++) {
      String minute = i.toString();
      if (i < 10) {
        minute = "0" + i.toString();
      }
      minuteData.add(minute);
    }
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  Widget buildItem(String text) {
    return Text(
      text,
      textAlign: TextAlign.center,
      softWrap: true,
      style: TextStyle(
        fontSize: 20,
        fontWeight: FontWeight.w500,
        fontStyle: FontStyle.normal,
        color: Color(0xFF333333),
        decoration: TextDecoration.none,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        width: widget.width,
        height: widget.height,
        color: Colors.white,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Container(
              width: widget.width,
              height: 50,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  TextButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                    child: Container(
                      height: 36,
                      width: 100,
                      color: Colors.transparent,
                      alignment: Alignment.center,
                      child: Text(
                        '取消',
                        style: TextStyle(fontSize: 15, color: Colors.black87),
                      ),
                    ),
                  ),
                  Expanded(
                    child: Text(
                      '${selectedHour}:${selectedminute}',
                      textAlign: TextAlign.center,
                      style: TextStyle(fontSize: 16, color: Colors.black87),
                    ),
                  ),
                  TextButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                    child: Container(
                      height: 36,
                      width: 100,
                      alignment: Alignment.center,
                      child: Text(
                        '确定',
                        style: TextStyle(fontSize: 15, color: Colors.blue),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            Expanded(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Container(
                    width: 150,
                    height: widget.height,
                    child: Scrollable(
                      axisDirection: AxisDirection.down,
                      physics: BouncingScrollPhysics(),
                      dragStartBehavior: DragStartBehavior.start,
                      viewportBuilder: (ctx, position) =>
                          ListWheelScrollView.useDelegate(
                        itemExtent: 44,
                        squeeze: 1,
                        diameterRatio: 3,
                        useMagnifier: true,
                        overAndUnderCenterOpacity: 0.8,
                        magnification: 1.1,
                        onSelectedItemChanged: (index) {
                          String hour = hourData[index];
                          print("hour:${hour}");
                          setState(() {
                            selectedHour = hour;
                          });
                        },
                        childDelegate: ListWheelChildLoopingListDelegate(
                            children:
                                hourData.map((e) => buildItem(e)).toList()),
                      ),
                    ),
                  ),
                  Container(
                    width: 150,
                    height: widget.height,
                    child: Scrollable(
                      axisDirection: AxisDirection.down,
                      physics: BouncingScrollPhysics(),
                      dragStartBehavior: DragStartBehavior.start,
                      viewportBuilder: (ctx, position) =>
                          ListWheelScrollView.useDelegate(
                        itemExtent: 44,
                        squeeze: 1,
                        diameterRatio: 3,
                        useMagnifier: true,
                        overAndUnderCenterOpacity: 0.8,
                        magnification: 1.1,
                        onSelectedItemChanged: (index) {
                          String minute = minuteData[index];
                          print("minute:${minute}");
                          setState(() {
                            selectedminute = minute;
                          });
                        },
                        childDelegate: ListWheelChildLoopingListDelegate(
                            children:
                                minuteData.map((e) => buildItem(e)).toList()),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ));
  }
}

    

效果图如下

在这里插入图片描述

三、小结

flutter开发实战-ListWheelScrollView与自定义TimePicker

学习记录,每天不停进步。


http://www.niftyadmin.cn/n/5534864.html

相关文章

使用React复刻ThreeJS官网示例——keyframes动画

最近在看three.js相关的东西&#xff0c;想着学习一下threejs给的examples。源码是用html结合js写的&#xff0c;恰好最近也在学习react&#xff0c;就用react框架学习一下。 本文参考的是threeJs给的第一个示例 three.js examples (threejs.org) 一、下载threeJS源码 通常我们…

【LC刷题】DAY22:491 46 47 332 51 37

【LC刷题】DAY22&#xff1a;491 46 47 332 51 37 文章目录 【LC刷题】DAY22&#xff1a;491 46 47 332 51 37491. 非递减子序列 [link](https://leetcode.cn/problems/non-decreasing-subsequences/description/)46. 全排列 [link](https://leetcode.cn/problems/permutations…

Kafka集群部署(手把手部署图文详细版)

1.1.1 部署zookpeer 在node02下载并解压zookeeper软件包 cd /usr/local wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz 或者&#xff1a;scp cat192.168.28.100:/home/cat/zookeeper-3.4.6.tar.gz /tmp&#xff08;注意目录&#xf…

Feign 原理流程图练习-01

目录 作业: 老师给的参考流程图 要求 解答 知识扩展 Feign基础原理 接口定义 代理对象生成 请求调用 请求发送 响应处理 容错与熔断 总结 作业: 老师给的参考流程图 pdf版本 【金山文档 | WPS云文档】 Feign https://kdocs.cn/l/ctbagIyxN348 ​ 要求 结合上面…

单例模式(下)

文章目录 文章介绍步骤安排及单例讲解step1&#xff1a;注册单例类型&#xff08;main.cpp&#xff09;step2&#xff1a;定义类和私有构造函数&#xff08;keyboardinputmanager.h&#xff09;step3:&#xff08;keyboardinputmanager.cpp&#xff09;step4&#xff1a;在qml中…

Neo4j 图数据库 高级操作

Neo4j 图数据库 高级操作 文章目录 Neo4j 图数据库 高级操作1 批量添加节点、关系1.1 直接使用 UNWIND 批量创建关系1.2 使用 CSV 文件批量创建关系1.3 选择方法 2 索引2.1 创建单一属性索引2.2 创建组合属性索引2.3 创建全文索引2.4 列出所有索引2.5 删除索引2.6 注意事项 3 清…

基于weixin小程序农场驿站系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;农场资讯管理&#xff0c;用户管理&#xff0c;卖家管理&#xff0c;用户分享管理&#xff0c;分享类型管理&#xff0c;商品信息管理&#xff0c;商品类型管理 开发系统&#xff1a;Windows 架构模式…

RClone挂载有阿里云的AList

转自个人博客&#xff1a;https://www.jjy2023.cn/2024/05/23/rclone%e6%8c%82%e8%bd%bd%e6%9c%89%e9%98%bf%e9%87%8c%e4%ba%91%e7%9a%84alist-md/ RClone挂载一般的AList可以直接使用mount命令&#xff0c;但是阿里云需要使用指定头部Referer:https://www.aliyundrive.com/ &a…