【问题标题】:Widget Architecture for Flutter AppFlutter App 的 Widget 架构
【发布时间】:2018-04-04 04:35:11
【问题描述】:

我正在制作这个应用程序,但不确定组织它的好方法。下面用图片来演示:

在哪里(目前):

  • 蓝色:无状态小部件 => ListView、行小部件
  • 红色:有状态小部件 => 扩展小部件
  • 绿色:无状态小部件 => 扩展小部件

应用需要做什么:数字需要在变化时自行更新(我现在不担心花哨的动画,只是过渡)。

问题:我发现更新这些数字的唯一方法是每分钟通过 Timer.periodic。但是,我发现很难路由此信息。我目前在每个 Red Expanded Widget 下都有我的定期计时器,但它们都有一个唯一的 DateTime。冗余信息是这种方法的问题。我可以在 Blue ListView、Rows Widget 中放置一个定期计时器。但是,每次更新都需要重新加载所有包含的小部件,包括绿色扩展小部件。

如果有任何建议或不同的方式,将不胜感激。

【问题讨论】:

    标签: android ios dart flutter


    【解决方案1】:

    Flutter 的设计意味着你重新加载绿色的 Widgets 并不重要;它的工作方式使它非常便宜。因此,将您的状态拖到包含所有文本/列/等的 StatefulWidget(现在可以是无状态的)。

    这个例子展示了一种下推状态片段的方法(进入 DurationPartWidget 的构造函数)。我已经证明您可以在构建方法中进行日期数学运算。同样,您可以在 setState 中执行此操作,并创建 _AnniversaryWidgetState 的年、月等实例变量。

    class AnniversaryWidget extends StatefulWidget {
      final DateTime firstDate;
    
      AnniversaryWidget(this.firstDate);
    
      @override
      State createState() {
        return new _AnniversaryWidgetState();
      }
    }
    
    class _AnniversaryWidgetState extends State<AnniversaryWidget> {
      Timer _timer;
    
      @override
      void initState() {
        super.initState();
        _timer = new Timer.periodic(new Duration(seconds: 1), (Timer t) {
          setState(() {});
        });
      }
    
      @override
      void dispose() {
        _timer.cancel();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        DateTime now = new DateTime.now();
        // todo - calculate these from now minus firstDate
        int years = 0;
        int months = 4;
        int days = 13;
        int hours = 21;
        int minutes = now.difference(widget.firstDate).inMinutes % 60;
        return new Center(
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new _DurationPartWidget('years', years),
              new _DurationPartWidget('months', months),
              new _DurationPartWidget('days', days),
              new _DurationPartWidget('hours', hours),
              new _DurationPartWidget('minutes', minutes),
            ],
          ),
        );
      }
    }
    
    class _DurationPartWidget extends StatelessWidget {
      final int _numberPart;
      final String _label;
    
      _DurationPartWidget(this._label, this._numberPart);
    
      @override
      Widget build(BuildContext context) {
        return new Row(
          children: <Widget>[
            new Text(_numberPart.toString().padLeft(2, '0')),
            new Text(_label),
          ],
        );
      }
    }
    

    如果以后,您想将状态带到 Widget 树的更高位置,您可以使用 InheritedWidget。 (我有时会使用 MaterialApp 上面的一个。)Brian Egan 在 DartConf 2018 上就​​整个主题发表了精彩的演讲。 https://www.youtube.com/watch?v=zKXz3pUkw9A&list=PLOU2XLYxmsIIJr3vjxggY7yGcGO7i9BK5&index=10

    【讨论】:

    • 今天我来看看视频。谢谢!
    猜你喜欢
    • 2020-04-24
    • 1970-01-01
    • 2019-04-01
    • 2019-03-14
    • 2019-10-16
    • 2019-07-06
    • 2021-09-16
    • 2020-12-11
    • 1970-01-01
    相关资源
    最近更新 更多