一切皆组件的Flutter,安能辨我是雄雌
从一开始接触Flutter,相信读者都会铭记一句话,那就是——一切皆组件。今天我们就来体会一下这句话的神奇魔力,我们先从实际的产品需求说起。
我们先来看一个简化的运行图:

我们要实现如上图所示的日期选择器,App是iOS风格。
Flutter SDK自身有类似上图的日期选择器,但是Material Design的,于是我到Flutter库中找到了一个名为flutter_date_pickers的三方库,版本为0.1.4(https://pub.flutter-io.cn/packages/flutter_date_pickers)。
接下来就是集成这个库了,具体代码按照文档直接复制:
@override
Widget build(BuildContext context) {
DatePickerRangeStyles styles = DatePickerRangeStyles(
selectedPeriodLastDecoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.only(
topRight: Radius.circular(10.0),
bottomRight: Radius.circular(10.0))),
selectedPeriodStartDecoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0), bottomLeft: Radius.circular(10.0)),
),
selectedPeriodMiddleDecoration:
BoxDecoration(color: Colors.yellow, shape: BoxShape.rectangle),
);
return CupertinoPageScaffold(
child: WeekPicker(
selectedDate: DateTime.now(),
onChanged: (dateRange) {},
firstDate: DateTime.now().subtract(Duration(days: 10)),
lastDate: DateTime.now().add(Duration(minutes: 10)),
datePickerStyles: styles)
);
}
本来以为可以正常运行的,结果整个App崩溃了。报错堆栈信息如下:
The following NoSuchMethodError was thrown building WeekPicker(dirty, dependencies: [_LocalizationsScope-[GlobalKey#678bc]]):
The getter 'firstDayOfWeekIndex' was called on null.
Receiver: null
Tried calling: firstDayOfWeekIndex
接着,根据堆栈信息找到代码出错位置,发现是这个库中week_picker.dart文件中出现问题,下面的代码是问题所在:
MaterialLocalizations localizations = MaterialLocalizations.of(context);
ISelectablePicker<DatePeriod> weekSelectablePicker = WeekSelectable(
selectedDate,
datePickerStyles.firstDayOfeWeekIndex ?? localizations.firstDayOfWeekIndex,
firstDate,
lastDate,
selectableDayPredicate: selectableDayPredicate
);
很明显,这里使用了MaterialLocalizations对象localizations,而MaterialLocalizations.of(context);方法返回了null,所以在接下来的代码中抛出了空指针异常。
解决的方法很简单,只要修改源码,如果通过MaterialLocalizations来初始化localizations得到null,那么就通过CupertinoLocalizations来初始化它就行了。具体代码如下:
CupertinoLocalizations localizations = CupertinoLocalizations.of(context);
在接下来的使用时,替换为:
localizations.datePickerDateOrder.index
即可。
但是,这毕竟需要改第三方库的源代码,有没有办法不改源码呢?答案是肯定的。
我们一开始就提到一切皆组件的概念,那么,有没有可能App依然使用iOS风格,然后把MaterialApp嵌套到CupertinoPageScaffold中呢?换一种说法,我们可不可以把MaterialApp和与之相关的Scaffold当做普通的组件,被CupertinoPageScaffold所包含呢?来看下面的代码:
@override
Widget build(BuildContext context) {
DatePickerRangeStyles styles = DatePickerRangeStyles(
selectedPeriodLastDecoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.only(
topRight: Radius.circular(10.0),
bottomRight: Radius.circular(10.0))),
selectedPeriodStartDecoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0), bottomLeft: Radius.circular(10.0)),
),
selectedPeriodMiddleDecoration:
BoxDecoration(color: Colors.yellow, shape: BoxShape.rectangle),
);
return CupertinoPageScaffold(
child: MaterialApp(
home: Scaffold(
appBar: CupertinoNavigationBar(middle: Text('Incredible Flutter')),
body: WeekPicker(
selectedDate: DateTime.now(),
onChanged: (dateRange) {},
firstDate: DateTime.now().subtract(Duration(days: 10)),
lastDate: DateTime.now().add(Duration(minutes: 10)),
datePickerStyles: styles))));
}
仔细阅读上述代码,可见:我们只是在return语句中增加了MaterialApp和Scaffold组件,重新运行程序,结果可以正常运行了。
另外还要注意,Scaffold中的appBar,我们经常给定的是AppBar对象,但为了实现iOS的界面风格,我们将其值改为CupertinoNavigationBar,也是没有问题的。
好了,本次分享到此结束,希望上述内容能够帮到你。
一切皆组件的Flutter,安能辨我是雄雌的更多相关文章
- python金牌班第七周周末总结
python金牌班第七周周末总结 面向对象前戏 1.我们在学习面相对像之前有一个推导过程如何将我们之前写的东西,从一串代码转向给对象服务. 2.实例 我们首先模拟了两个物种进行战斗的场景,然后我们发现 ...
- 理清C++常量指针和指针常量这团乱麻
写在前面: 与其说C++中的常量指针和指针常量是一块很有嚼头的语法糖,不如说它是一块相当难啃的骨头.其实本来没什么,这无非是const int *p与int* const p的区别, 但一涉及到起名字 ...
- Java开发笔记(五十二)对象的类型检查
前面介绍了类的多态性,来自于鸡类的实例chicken,既能用来表达公鸡实例,也能用来表达母鸡实例.可是这导致了一个问题,假如在call方法内部需要手工判断输入参数属于公鸡实例还是母鸡实例,那该如何是好 ...
- Flutter 中那么多组件,难道要都学一遍?
在 Flutter 中一切皆是 组件,仅仅 Widget 的子类和间接子类就有 350 多个,整理的 Flutter组件继承关系图 可以帮助大家更好的理解学习 Flutter,回归正题,如此多的组件到 ...
- 【老孟Flutter】Stateful 组件的生命周期
老孟导读:关于生命周期的文章共有2篇,第一篇是介绍 Flutter 中Stateful 组件的生命周期. 博客地址:http://laomengit.com/blog/20201227/Statefu ...
- Flutter 目录结构介绍、入口、自定义 Widget、MaterialApp 组件、Scaffold 组件
Flutter 目录结构介绍 文件夹 作用 android android 平台相关代码 ios ios 平台相关代码 lib flutter 相关代码,我们主要编写的代 码就在这个文件夹 test ...
- flutter Container组件和Text组件
在开始之前,我们先写一个最简单的入口文件: 后面,都是在这个结构的基础上面完成的. 由于Container组件和Text组件都是写在body里面的,所以下面,先将body抽离成一个组件的形式. ...
- 【Flutter学习】组件学习之目录
01. Flutter组件-Layout-Container-容器 02. Flutter组件-Text-Text-文本 03. Flutter组件-Text-RichText-富文本 04. ...
- Flutter 中的常见的按钮组件 以及自 定义按钮组件
一.Flutter 中的按钮组件介绍 Flutter 里有很多的 Button 组件很多,常见的按钮组件有:RaisedButton.FlatButton. IconButton.Outlin ...
随机推荐
- 【Xamarin.Forms 3】页面类型
系列目录 微信 1.[Xamarin.Forms 1]App的创建与运行 2.[Xamarin.Forms 2]App基础知识与App启动 知乎 1.[Xamarin.Forms 1]App的创建与运 ...
- 《算法笔记》6.7小节 问题 A: 简单计算器
又是大模拟淦淦淦淦淦淦淦 思路: 这道题我居然用的队列orz. 言归正传,这道题就是模拟计算器.从读题目样例可以发现,数字的个数只比符号的个数多一个,那么这就给我们了思路:用队列,先提前放出一个数,每 ...
- 如何将less编译成css文件__less自动编译成css的方法总结
作为css的预处理less,拥有着比css更快捷方便,扩展了css的变量.Mixin.函数等特性,使 CSS 更易维护和扩展. 如何你已经回使用css,那么less就很容易上手了.如果不使用less ...
- 一起来看 HTML 5.2 中新的原生元素 <dialog>
不到一个月前,HTML 5.2 正式成为 W3C 的推荐标准(REC),其中,推出了一个新的原生模态对话框元素 <dialog>,乍一看,可能感觉它就是一个新增的元素,然而,作者最近在玩的 ...
- Navicat远程连接MySQL 提示1045 - Access denied for user 'root'@'223.74.158.192'(using password:YES)
问题: 今天在自己的阿里云服务器上(Window Server2012 R2)安装了一个MySQL5.7.26,在阿里云服务器中通过本地链接是正常的,但是当在自己的电脑上使用Navicat连接是提示: ...
- P2882 Face The Right Way G 题解
题目 Farmer John has arranged his N \((1 ≤ N ≤ 5,000)\) cows in a row and many of them are facing forw ...
- When Lambo with Howdoo
原文链接:https://howdoo.io/when-lambo/ 为了庆祝即将推出的革命性新社交媒体平台Howdoo以及我们令人惊喜的合作伙伴关系和社区,我们正在发起一项竞赛,以最终回答“When ...
- Creator填色游戏的一种实现方案
前言 先上一个辛苦弄出来的gif效果.写公众号时间不长,很多技巧还在慢慢跟小伙伴学习.可关注公众号,回复"绘图"或者"填色"都可获得demo的git地址.请使用 ...
- SQLserver-MySQL的区别和用法
对于程序开发人员而言,目前使用最流行的两种后台数据库即为MySQL and SQL Server.这两者最基本的相似之处在于数据存储和属于查询系统.你可以使用SQL来访问这两种数据库的数据,因为它们都 ...
- 阿里云OSS 服务端签名后直传之分片上传(结合element-ui的upload组件)
分片上传(结合element-ui的upload组件实现自定义上传) async uploadFree(content){ let data = await this.getOssToken(); / ...