• Flutter学习笔记(四)--Flutter几个小知识点


    Flutter的Widget采用的是现代化的React风格,该风格的设计灵感来源于React这么语言。最核心的理念是你可以使用Widget设计界面。Widget通过当前的state和注册信息来描述view应该长成什么样子的。当当前的状态发生了变化后,Widget会重新构建。

    一、Hello World

    void main() {
      runApp(
        new Center(
          child: new Text(
            'Hello, world!',
            textDirection: TextDirection.ltr,
          ),
        ),
      );
    }
    

    上面是一个简单的Widget。
    这里,可以总结出如下几点:

    • runApp()方法制定了根Widget,其他的Widget都应该是该Widget的子Widget
    • 默认会强制根Widget是覆盖全屏幕的
      除此之外,还有:
    • 自己创建的Widget应该是StatefulWidget或者StatelessWidget的子类,到底是哪个的子类,取决于该Widget是否需要管理一些state

    二、StatefulWidget和State

    为什么要将Widget和State分别写到两个类里呢?
    上一节最后说到,我们将状态管理放到Widget里,是有问题的,有什么问题呢?这里在Widget和State里分别添加一个num属性,我每点击一次,对两个的num都加1,代码如下:

    class _ParentWidget extends StatefulWidget {
      bool active = false;
      var num = 0;
      @override
      State<StatefulWidget> createState() => new _ParentWidgetState();
    }
    
    class _ParentWidgetState extends State<_ParentWidget> {
    
      void _handleTapboxChanged(bool newValue) {
        setState(() {
          widget.active = newValue;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        print("Parent State:${widget.num}");
        widget.num += 1;
        // TODO: implement build
        return new Container(
          child: new TapboxC(onChanged: _handleTapboxChanged, active: widget.active),
            );
      }
    }
    
    typedef void changedValue(bool newValue);
    
    class TapboxC extends StatefulWidget {
      var num = 0;
      final bool _active;
      bool _highlight = false;
      changedValue changed;
    //  final ValueChanged<bool> onChanged;
      TapboxC({Key key, bool active, @required changedValue onChanged})
          :this._active = active, this.changed = onChanged, super(key: key) { }
      @override
      State<StatefulWidget> createState() {
        print("TapBoxC createState");
        return new _TapboxCState();
      }
    }
    
    class _TapboxCState extends State<TapboxC> {
      var num = 0;
      void _handleTap() {
        widget.changed(!widget._active);
      }
    
      void _handleTapDown(TapDownDetails details) {
        setState((){
          widget._highlight = true;
        });
      }
    
      void _handleTapUp(TapUpDetails details) {
        setState((){
          widget._highlight = false;
        });
      }
    
      void _handleTapCancel(){
        setState((){
          widget._highlight = false;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        print("_TapboxCState build:${widget.num}, this num:$num");
        num += 1;
        widget.num += 1;
        // TODO: implement build
        return new GestureDetector(
          onTap: _handleTap,
          onTapDown: _handleTapDown,
          onTapUp: _handleTapUp,
          onTapCancel: _handleTapCancel,
          child: new Container(
             200.0,
            height: 200.0,
            decoration: new BoxDecoration(
              color: widget._active ? Colors.lightGreen[700] : Colors.grey[600],
              border: widget._highlight
                  ? new Border.all(color: Colors.teal[700],  10.0)
                  : null,
            ),
          ),
        );
      }
    }
    
    最后的结果如下:
    image.png

    你会发现,TapboxC的num一直在0和1之间跳动,而ParentWidget和TapboxCState的num都是递增的。这是为什么呢?
    首先明确的是,每次回调改变ParentWidget的State时,都会重新初始化一次TapboxC,所以它的num每次都会变为0就不奇怪了,而因为ParentWidget并没有改变,所以会递增。
    可能又有疑惑,那么为什么TabboxCState的num就不归0呢?
    其实这都是和Widget和State 的生命周期有关。Widget相当于时一个暂时的对象,只是为了展示和布局当前状态时用的,一旦状态发生了改变,它就会失效;而State从某种角度来说是个永久对象,它里面存储了一些必要信息,这其实也是React的一个特性,即每次通过比较,只更新和修改差异化的东西。

  • 相关阅读:
    python3 入门
    Python2 的列表排序
    数据库阻塞SQL的隔离级别
    数据库阻塞讲解设计应用程序时避免阻塞的八个准则
    DELPHI学习简单类型
    DELPHI学习结构类型
    InsideVCL第3章面向对象程序语言和Framework
    数据库阻塞分析死锁并处理
    面向对象开发实践之路
    DELPHI hint 的应用
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/10528961.html
Copyright © 2020-2023  润新知