一切皆组件的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 ...
随机推荐
- 117.填充每个节点的下一个右侧节点指针II
# Definition for a Node.class Node: def __init__(self, val: int = 0, left: 'Node' = None, right: 'No ...
- VSCode 使用 Settings Sync 同步配置和插件
简要说明: Settings Sync插件可以在不同的计算机同步VSCode配置和插件. 安装和配置 在VSCode的插件栏搜索settings sync并安装.在安装完成之后如果需要重新载入就点击重 ...
- Lists.newArrayList() 和 new ArrayList()的区别?
什么是创建List字符串的最好构造方法?是Lists.newArrayList()还是new ArrayList()? 还是个人喜好? Lists和Maps是两个工具类, Lists.newArray ...
- JAVA7新属性之放宽switch的使用限制
在Java7发布之后,关于switch的用法上,除了char,byte,short,int之外,允许了String.例如(不可以为null): public class Title { public ...
- 【Oracle】rman中SBT_TYPE类型的备份如何删除
技阳的rman数据库出现删除rman备份失败,原因是出现SBT_TYPE的磁带备份. [BEGIN] 2018/8/13 13:48:42 RMAN> list backup; List of ...
- JS数据类型判断的几种方法
JS数据类型判断 JavaScript 中常见数据类型有Number.String.Boolean.Object.Array.Json.Function.Date.RegExp.Error.undef ...
- 每日一题 - 剑指 Offer 32 - III. 从上到下打印二叉树 III
题目信息 时间: 2019-06-25 题目链接:Leetcode tag:双端队列 难易程度:中等 题目描述: 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右 ...
- Python——格式化GMT时间
1.背景 最近在做视频上传去获取大小.时间的功能,视频是存在金山云的,由于金山sdk接口用例执行后返回的结果中的时间是http头部时间,时间格式为‘Tue, 08 May 2018 06:17:00 ...
- linux篇---根据端口号查看进程位置
1)说明:Linux的所有进程都保存在/proc/目录下,保存形式为:/proc/进程号.进入到进程号目录后,里面有一个cwd链接文件即指向的进程的的目录. 2) 操作: A:根据端口号查进程 如:l ...
- 记一道CTF隐写题解答过程
0x00 前言 由于我是这几天才开始接触隐写这种东西,所以作为新手我想记录一下刚刚所学.这道CTF所需的知识点包括了图片的内容隐藏,mp3隐写,base64解密,当铺解密,可能用到的工具包括bin ...