美文网首页编程二三事
一切皆组件的FLUTTER,安能辨我是雄雌

一切皆组件的FLUTTER,安能辨我是雄雌

作者: 萧文翰 | 来源:发表于2020-07-27 13:21 被阅读0次

从一开始接触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,安能辨我是雄雌

    从一开始接触Flutter,相信读者都会铭记一句话,那就是——一切皆组件。今天我们就来体会一下这句话的神奇魔力,我...

  • 安能辨我是雄雌

    虫虫在地上爬,它看见了一只蜗牛,虫虫知道他身上刚蹭到了地上的盐,不能靠近蜗牛。因为蜗牛一碰到盐,就会融化。于...

  • 安能辨我是雄雌?

    这几天跟王先生一起看了不少的综艺,像是爱奇艺的《少年说唱企划》,浙江卫视的《好声音》,还有腾讯视频的《脱口秀大会》...

  • 是的,我很嚣张

    雄兔脚扑朔,雌兔眼迷离。双兔傍地走,安能辨我是雄雌。 ——《木兰诗》 你就是...

  • 瑞兔

    雄兔脚扑朔,雌兔眼迷离。 双兔傍地走,安能辨我是雄雌。 注: 手绘为原创,禁止转载。

  • 伪类与伪元素,傻傻分不清楚

    我记的在《木兰辞》里面有一句“雄兔脚扑朔, 雌兔眼迷离; 双兔傍地走, 安能辨我是雄雌?”我觉得我现在就是那个辨雌...

  • 兔麻麻和孩子们

    作为昨天那副作品的替代 “双兔傍地走 安能辨我是雄雌”

  • 🌻每天学诗:木兰诗 / 木兰辞 .6

    雄兔脚扑朔,雌兔眼迷离;双兔傍地走,安能辨我是雄雌? (据说,提着兔子的耳朵悬在半空时)雄兔两只前脚时常动弹,雌兔...

  • 原创 并蒂莲

    雄兔脚扑朔,雌兔眼迷离。双兔傍地走,安能辨我是雌雄。 ____《木兰...

网友评论

    本文标题:一切皆组件的FLUTTER,安能辨我是雄雌

    本文链接:https://www.haomeiwen.com/subject/morzlktx.html