当前位置: 首页 > news >正文

flutter日期选择器仅选择年、月

在这里插入图片描述
引入包:flutter_datetime_picker: 1.5.0
封装

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';class ATuiDateTimePicker {static Future<DateTime> showDatePicker(BuildContext context, {bool showTitleActions: true,bool isShowDay: true,DateTime minTime,DateTime maxTime,DateChangedCallback onChanged,DateChangedCallback onConfirm,DateCancelledCallback onCancel,locale: LocaleType.en,DateTime currentTime,DatePickerTheme theme,}) async {return await Navigator.push(context,_DatePickerRoute(showTitleActions: showTitleActions,onChanged: onChanged,onConfirm: onConfirm,onCancel: onCancel,locale: locale,theme: theme,isShowDay: isShowDay,barrierLabel:MaterialLocalizations.of(context).modalBarrierDismissLabel,pickerModel: DatePickerModel(currentTime: currentTime,maxTime: maxTime,minTime: minTime,locale: locale,),),);}
}class _DatePickerRoute<T> extends PopupRoute<T> {_DatePickerRoute({this.showTitleActions,this.onChanged,this.onConfirm,this.onCancel,theme,this.barrierLabel,this.locale,this.isShowDay,RouteSettings settings,pickerModel,})  : this.pickerModel = pickerModel ?? DatePickerModel(),this.theme = theme ?? DatePickerTheme(),super(settings: settings);final bool showTitleActions;final DateChangedCallback onChanged;final DateChangedCallback onConfirm;final DateCancelledCallback onCancel;final DatePickerTheme theme;final LocaleType locale;final BasePickerModel pickerModel;final bool isShowDay;Duration get transitionDuration => const Duration(milliseconds: 200);bool get barrierDismissible => true;final String barrierLabel;Color get barrierColor => Colors.black54;AnimationController _animationController;AnimationController createAnimationController() {assert(_animationController == null);_animationController =BottomSheet.createAnimationController(navigator.overlay);return _animationController;}Widget buildPage(BuildContext context, Animation<double> animation,Animation<double> secondaryAnimation) {Widget bottomSheet = MediaQuery.removePadding(context: context,removeTop: true,child: _DatePickerComponent(onChanged: onChanged,locale: this.locale,route: this,pickerModel: pickerModel,isShowDay: isShowDay,),);return InheritedTheme.captureAll(context, bottomSheet);}
}class _DatePickerComponent extends StatefulWidget {_DatePickerComponent({Key key, this.route,this.onChanged,this.locale,this.pickerModel,this.isShowDay}): super(key: key);final DateChangedCallback onChanged;final _DatePickerRoute route;final LocaleType locale;final BasePickerModel pickerModel;final bool isShowDay;State<StatefulWidget> createState() {return _DatePickerState();}
}class _DatePickerState extends State<_DatePickerComponent> {FixedExtentScrollController leftScrollCtrl, middleScrollCtrl, rightScrollCtrl;void initState() {super.initState();refreshScrollOffset();}void refreshScrollOffset() {
//    print('refreshScrollOffset ${widget.pickerModel.currentRightIndex()}');leftScrollCtrl = FixedExtentScrollController(initialItem: widget.pickerModel.currentLeftIndex());middleScrollCtrl = FixedExtentScrollController(initialItem: widget.pickerModel.currentMiddleIndex());rightScrollCtrl = FixedExtentScrollController(initialItem: widget.pickerModel.currentRightIndex());}Widget build(BuildContext context) {DatePickerTheme theme = widget.route.theme;return GestureDetector(child: AnimatedBuilder(animation: widget.route.animation,builder: (BuildContext context, Widget child) {final double bottomPadding = MediaQuery.of(context).padding.bottom;return ClipRect(child: CustomSingleChildLayout(delegate: _BottomPickerLayout(widget.route.animation.value,theme,showTitleActions: widget.route.showTitleActions,bottomPadding: bottomPadding,),child: GestureDetector(child: Material(color: theme.backgroundColor ?? Colors.white,child: _renderPickerView(theme),),),),);},),);}void _notifyDateChanged() {if (widget.onChanged != null) {widget.onChanged(widget.pickerModel.finalTime());}}Widget _renderPickerView(DatePickerTheme theme) {Widget itemView = _renderItemView(theme);if (widget.route.showTitleActions) {return Column(children: <Widget>[_renderTitleActionsView(theme),itemView,],);}return itemView;}Widget _renderColumnView(ValueKey key,DatePickerTheme theme,StringAtIndexCallBack stringAtIndexCB,ScrollController scrollController,int layoutProportion,ValueChanged<int> selectedChangedWhenScrolling,ValueChanged<int> selectedChangedWhenScrollEnd,) {return Expanded(flex: layoutProportion,child: Container(padding: EdgeInsets.all(8.0),height: theme.containerHeight,decoration: BoxDecoration(color: theme.backgroundColor ?? Colors.white),child: NotificationListener(onNotification: (ScrollNotification notification) {if (notification.depth == 0 &&selectedChangedWhenScrollEnd != null &&notification is ScrollEndNotification &&notification.metrics is FixedExtentMetrics) {final FixedExtentMetrics metrics = notification.metrics;final int currentItemIndex = metrics.itemIndex;selectedChangedWhenScrollEnd(currentItemIndex);}return false;},child: CupertinoPicker.builder(key: key,backgroundColor: theme.backgroundColor ?? Colors.white,scrollController: scrollController,itemExtent: theme.itemHeight,onSelectedItemChanged: (int index) {selectedChangedWhenScrolling(index);},useMagnifier: true,itemBuilder: (BuildContext context, int index) {final content = stringAtIndexCB(index);if (content == null) {return null;}return Container(height: theme.itemHeight,alignment: Alignment.center,child: Text(content,style: theme.itemStyle,textAlign: TextAlign.start,),);},),),),);}Widget _renderItemView(DatePickerTheme theme) {return Container(color: theme.backgroundColor ?? Colors.white,child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,children: <Widget>[Container(child: widget.pickerModel.layoutProportions()[0] > 0? _renderColumnView(ValueKey(widget.pickerModel.currentLeftIndex()),theme,widget.pickerModel.leftStringAtIndex,leftScrollCtrl,widget.pickerModel.layoutProportions()[0], (index) {widget.pickerModel.setLeftIndex(index);}, (index) {setState(() {refreshScrollOffset();_notifyDateChanged();});}): null,),Text(widget.pickerModel.leftDivider(),style: theme.itemStyle,),Container(child: widget.pickerModel.layoutProportions()[1] > 0? _renderColumnView(ValueKey(widget.pickerModel.currentLeftIndex()),theme,widget.pickerModel.middleStringAtIndex,middleScrollCtrl,widget.pickerModel.layoutProportions()[1], (index) {widget.pickerModel.setMiddleIndex(index);}, (index) {setState(() {refreshScrollOffset();_notifyDateChanged();});}): null,),Text(widget.pickerModel.rightDivider(),style: theme.itemStyle,),widget.isShowDay ?? true? Container(child: widget.pickerModel.layoutProportions()[2] > 0? _renderColumnView(ValueKey(widget.pickerModel.currentMiddleIndex() * 100 +widget.pickerModel.currentLeftIndex()),theme,widget.pickerModel.rightStringAtIndex,rightScrollCtrl,widget.pickerModel.layoutProportions()[2], (index) {widget.pickerModel.setRightIndex(index);}, (index) {setState(() {refreshScrollOffset();_notifyDateChanged();});}): null,): Container(),],),);}// Title ViewWidget _renderTitleActionsView(DatePickerTheme theme) {final done = _localeDone();final cancel = _localeCancel();return Container(height: theme.titleHeight,decoration: BoxDecoration(color: theme.headerColor ?? theme.backgroundColor ?? Colors.white,),child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,children: <Widget>[Container(height: theme.titleHeight,child: CupertinoButton(pressedOpacity: 0.3,padding: EdgeInsets.only(left: 16, top: 0),child: Text('$cancel',style: theme.cancelStyle,),onPressed: () {Navigator.pop(context);if (widget.route.onCancel != null) {widget.route.onCancel();}},),),Container(height: theme.titleHeight,child: CupertinoButton(pressedOpacity: 0.3,padding: EdgeInsets.only(right: 16, top: 0),child: Text('$done',style: theme.doneStyle,),onPressed: () {Navigator.pop(context, widget.pickerModel.finalTime());if (widget.route.onConfirm != null) {widget.route.onConfirm(widget.pickerModel.finalTime());}},),),],),);}String _localeDone() {return i18nObjInLocale(widget.locale)['done'];}String _localeCancel() {return i18nObjInLocale(widget.locale)['cancel'];}
}class _BottomPickerLayout extends SingleChildLayoutDelegate {_BottomPickerLayout(this.progress,this.theme, {this.itemCount,this.showTitleActions,this.bottomPadding = 0,});final double progress;final int itemCount;final bool showTitleActions;final DatePickerTheme theme;final double bottomPadding;BoxConstraints getConstraintsForChild(BoxConstraints constraints) {double maxHeight = theme.containerHeight;if (showTitleActions) {maxHeight += theme.titleHeight;}return BoxConstraints(minWidth: constraints.maxWidth,maxWidth: constraints.maxWidth,minHeight: 0.0,maxHeight: maxHeight + bottomPadding,);}Offset getPositionForChild(Size size, Size childSize) {final height = size.height - childSize.height * progress;return Offset(0.0, height);}bool shouldRelayout(_BottomPickerLayout oldDelegate) {return progress != oldDelegate.progress;}
}

引用

GestureDetector(
child: Container(width:100,height:45,color:Colors.red)
onTap: (){LocaleType localeType;await ATuiSharedPreferences.getStorage("localType").then((value) {if (value == "zh") {localeType = LocaleType.zh;} else if (value == "en") {localeType = LocaleType.en;}});ATuiDateTimePicker.showDatePicker(context,isShowDay: false,locale: localeType ?? LocaleType.zh,theme: DatePickerTheme(cancelStyle: TextStyle(fontSize: 30.sp,color: Color(0xff5dc8b6),fontWeight: FontWeight.w600),doneStyle: TextStyle(fontSize: 30.sp,color: Color(0xff5dc8b6),fontWeight: FontWeight.w600)),onConfirm: (datetime) async {String newDate = '${datetime.year}-';newDate += datetime.month < 10? '0${datetime.month}': datetime.month.toString();walletListModel.changeDate(newDate);walletListModel.changeShowDate('${datetime.year}${datetime.month}月');walletListModel.refreshData();},onChanged: (datetime) {print('dateTime: ${datetime}');},);},
)

相关文章:

flutter日期选择器仅选择年、月

引入包&#xff1a;flutter_datetime_picker: 1.5.0 封装 import package:flutter/cupertino.dart; import package:flutter/material.dart; import package:flutter_datetime_picker/flutter_datetime_picker.dart;class ATuiDateTimePicker {static Future<DateTime> …...

素数筛详解c++

一、埃式筛法 代码 二、线性筛法&#xff08;欧拉筛法&#xff09; 主要的思想就是一个质数的倍数(倍数为1除外)肯定是合数&#xff0c;那么我们利用这个质数算出合数&#xff0c;然后划掉这个合数&#xff0c;下次就可以不用判断它是不是质数&#xff0c;节省了大量的时间。 …...

【Python超详细的学习笔记】Python超详细的学习笔记,涉及多个领域,是个很不错的笔记

获取笔记链接 Python超详细的学习笔记 一&#xff0c;逆向加密模块 1&#xff0c;Python中运行JS代码 1.1 解决中文乱码或者报错问题 import subprocess from functools import partial subprocess.Popen partial(subprocess.Popen, encodingutf-8) import execjs1.2 常用…...

TINA 使用教程

常用功能 分析-电气规则检查&#xff1a;短路&#xff0c;断路等分析- 直流分析 交流分析 瞬态分析 视图-分离曲线 由于输出的容性负载导致的振荡 增加5欧电阻后OK 横扫参数 添加横扫曲线的电阻&#xff0c;选择R3&#xff1a;8K-20K PWL和WAV文件的支持 示例一&#xff1a;…...

weblogic 任意文件上传 CVE-2018-2894

一、漏洞简介 在 Weblogic Web Service Test Page 中存在一处任意文件上传漏洞&#xff0c; Web Service Test Page 在"生产模式"下默认不开启&#xff0c;所以该漏洞有一定限制。利用该 漏洞&#xff0c;可以上传任意 jsp 文件&#xff0c;进而获取服务器权限。 二…...

我的第一个网页:武理天协

1. html代码 1.1 首页.html <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><title>武理天协</title><link rel"stylesheet" href"./style.css"><link rel"stylesh…...

机器学习笔记 KAN网络架构简述(Kolmogorov-Arnold Networks)

一、简述 在最近的研究中,出现了号称传统多层感知器 (MLP) 的突破性替代方案,重塑了人工神经网络 (ANN) 的格局。这种创新架构被称为柯尔莫哥洛夫-阿诺德网络 (KAN),它提出了一种受柯尔莫哥洛夫-阿诺德表示定理启发的函数逼近的方法。 与 MLP 不同,MLP 依赖于各个节…...

基于网络爬虫技术的网络新闻分析(二)

目录 2 系统需求分析 2.1 系统需求概述 2.2 系统需求分析 2.2.1 系统功能要求 2.2.2 系统IPO图 2.2 系统非功能性需求分析 3 系统概要设计 3.1 设计约束 3.1.1 需求约束 3.1.2 设计策略 3.1.3 技术实现 3.3 模块结构 3.3.1 模块结构图 3.3.2 系统层次图 3.3.3…...

Java--初识类和对象

前言 本篇讲解Java类和对象的入门版本。 学习目的&#xff1a; 1.理解什么是类和对象。 2.引入面向对象程序设计的概念 3.学会如何定义类和创建对象。 4.理解this引用。 5.了解构造方法的概念并学会使用 考虑到篇幅过长问题&#xff0c;作者决定分多次发布。 面向对象的引入 J…...

SpringBoot如何实现动态数据源?

在Spring Boot中实现动态数据源主要涉及到创建和管理不同的数据源&#xff0c;并在运行时根据需要切换。这可以通过编程方式配置Spring的AbstractRoutingDataSource来完成。下面我会逐步介绍如何实现动态数据源&#xff0c;并给出代码示例。 第1步&#xff1a;添加依赖 首先&…...

win10安装mysql8.0+汉化

一、官网安装 MySQL 1. 在mysql官网进行下载页面 2. 下滑页面&#xff0c;选择 MySQL community download 3.下载windows版本 4.选择第二个download 5.不用登陆&#xff0c;no thanks&#xff0c;just start my download. 6.下载 二、安装 1. 双击安装 2. 选 Full->next 3…...

全网最全的Postman接口自动化测试!

该篇文章针对已经掌握 Postman 基本用法的读者&#xff0c;即对接口相关概念有一定了解、已经会使用 Postman 进行模拟请求的操作。 当前环境&#xff1a; Window 7 - 64 Postman 版本&#xff08;免费版&#xff09;&#xff1a;Chrome App v5.5.3 不同版本页面 UI 和部分…...

Spring:了解@Import注解的三种用法

一、前言 在 Spring 框架中&#xff0c;Import 注解用于导入配置类&#xff0c;使得你可以在一个配置类中引入另一个或多个配置类&#xff0c;从而实现配置的模块化。这对于组织大型应用程序的配置非常有用&#xff0c;因为它允许你将配置分散到多个类中&#xff0c;然后再将它…...

简要介绍三大脚本语言 Shell、Python 和 Lua

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 脚本语言是一种用于自动化操作系统任务和应用程序功能的编程语言。它们通常用于编写小到中等规模的程序&#xff0c;以提高任务执行的速度和效率。在众多脚本语言中&#xff0c;Shell、Python 和 Lua 是…...

第 397 场 LeetCode 周赛题解

A 两个字符串的排列差 模拟&#xff1a;遍历 s s s 记录各字符出现的位置&#xff0c;然后遍历 t t t 计算排列差 class Solution {public:int findPermutationDifference(string s, string t) {int n s.size();vector<int> loc(26);for (int i 0; i < n; i)loc[s…...

文件存储解决方案-阿里云OSS

文章目录 1.菜单分级显示问题1.问题引出1.苹果灯&#xff0c;放到节能灯下面也就是id大于1272.查看菜单&#xff0c;并没有出现苹果灯3.放到灯具下面id42&#xff0c;就可以显示 2.问题分析和解决1.判断可能出现问题的位置2.找到递归返回树形菜单数据的位置3.这里出现问题的原因…...

基于Java的飞机大战游戏的设计与实现(论文 + 源码)

关于基于Java的飞机大战游戏.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89313362 基于Java的飞机大战游戏的设计与实现 摘 要 现如今&#xff0c;随着智能手机的兴起与普及&#xff0c;加上4G&#xff08;the 4th Generation mobile communication &#x…...

Vue路由开启步骤

1.在控制台输入命令 //控制台下载安装npm add vue-router3.6.5 2.在main.js下导入并注册组件 import Vue from vue import App from ./App.vue//控制台下载安装npm add vue-router3.6.5 //导入 import VueRouter from "vue-router";//注册 Vue.use(VueRouter) con…...

【碎片知识】2024_05_15

char int long float double运算的时候是从低转到高的&#xff0c;表达式的类型会自动提升或者转 换为参与表达式求值的最上级类型. 关于代码的说法正确的是&#xff08; &#xff09; #include <stdio.h> int main() {int x -1;unsigned int y 2;if (x > y){printf…...

彩虹聚合DNS管理系统

聚合DNS管理系统可以实现在一个网站内管理多个平台的域名解析&#xff0c;目前已支持的域名平台有&#xff1a;阿里云、腾讯云、华为云、西部数码、CloudFlare。本系统支持多用户&#xff0c;每个用户可分配不同的域名解析权限&#xff1b;支持API接口&#xff0c;支持获取域名…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...