flutter08 - widget

About Widget

concept

Flutter almost all objects are a Widget, the Widget Flutter concept broader, it can not only represent UI elements, it may also represent a number of functional components, such as: means for detecting a gesture of the GestureDetectorwidget, for APP theme data transfer the Themeso forth,

widget and Element

  • Widget is actually Elementthe configuration data, Widget configuration tree is actually a tree, and the tree is the real UI rendered by the Elementconstitution; however, as Elementis generated by Widget, so there is correspondence between them, in most scenes, we Widget can be broadly considered the tree refers to a tree or UI UI controls render tree.
  • Widget object may correspond to a plurality of Elementobjects. This is well understood, in accordance with a configuration (Widget), you can create multiple instances (Element).

Widget main window

@immutable
abstract class Widget extends DiagnosticableTree {
  const Widget({ this.key });
  final Key key;

  @protected
  Element createElement();

  @override
  String toStringShort() {
    return key == null ? '$runtimeType' : '$runtimeType-$key';
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense;
  }

  static bool canUpdate(Widget oldWidget, Widget newWidget) {
    return oldWidget.runtimeType == newWidget.runtimeType
        && oldWidget.key == newWidget.key;
  }
}
  • WidgetClass inherits from DiagnosticableTree, DiagnosticableTreenamely "diagnostic tree", the main role is to provide debugging information.
  • Key: This keyattribute is similar to React / Vue in the keymain role is to decide whether the next buildtime multiplexing old widget, the conditions in the decision canUpdate()process.
  • createElement(): As mentioned earlier, "may correspond to a plurality of Widget Element"; Flutter Framework UI when building the tree, will call this method to generate a corresponding node Elementobject. This method is called Flutter Framework implicit in our development process basically does not call into.
  • debugFillProperties(...) Replication method of the parent class, mainly to set the diagnosis of some of the features tree.
  • canUpdate(...)Is a static method, it is mainly used in the Widget tree again buildwhen reuse old widget, in fact, specifically, should be: whether with a new Widget object to update the old UI tree corresponding Elementconfiguration object; through its source code we can see, as long as newWidgetwith oldWidgetthe runtimeTypeand keywill use simultaneously equal newWidgetto update the Elementconfiguration objects, otherwise it will create a new Element.

StatelessWidget

Role: the scene does not need to maintain state, which is usually buildconstructed by a nested UI Widget other methods, the build process would be to build their nested recursive Widget.

Inherited from Widgetclass, override the createElement()method:

@override
StatelessElement createElement() => new StatelessElement(this);

Context

context is BuildContextan instance of a class, represents a context of the current widget in the widget tree, each corresponding to a widget will be a context object (widget is a widget because each node of a tree).

StatefulWidget

StatefulWidget is inherited from the Widget class, and rewriting the createElement () method, the difference is not the same as Element object returned; StatefulWidget further adds a new class interface createState ()

abstract class StatefulWidget extends Widget {
  const StatefulWidget({ Key key }) : super(key: key);

  @override
  StatefulElement createElement() => new StatefulElement(this);

  @protected
  State createState();
}
  • StatefulElementIndirect inherited from Elementclass with corresponding StatefulWidget (as configuration data). StatefulElementIt may be called multiple times createState()to create the state (State) objects.
  • createState()And Stateful widget for creating state-related, it may be called multiple times in the Stateful widget's life cycle. For example, when a plurality of positions simultaneously inserted into the Stateful widget widget tree, Flutter framework will call this method for each location to generate a separate State instances, in fact, essentially a StatefulElementcorresponds to a State example.

state Lifecycle

import 'package:flutter/material.dart';

void main() => runApp(CounterWidget(
      initValue: 10,
    ));

class CounterWidget extends StatefulWidget {
  final int initValue;

  const CounterWidget({Key key, this.initValue});

  @override
  _CounterWidgetState createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter;


  /**
   * 第一次被调用
   */
  @override
  void initState() {
    super.initState();
    //初始化状态
    _counter = widget.initValue;
    print("生命周期:initState");
  }

  @override
  Widget build(BuildContext context) {
    print("生命周期:build");

    return MaterialApp(
      title: "计数器",
      home: Scaffold(
        appBar: AppBar(
          title: Text("计数器"),
        ),
        body: Center(
          child: FlatButton(
            child: Text("$_counter"),
            //点击后计数器自增
            onPressed: () => setState(() => ++_counter),
          ),
        ),
      ),
    );
  }

  //在新旧widget的key和runtimeType同时相等时didUpdateWidget()就会被调用
  @override
  void didUpdateWidget(CounterWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    print("生命周期:didUpdateWidget");
  }

  //state对象从树中被移除时调用
  @override
  void deactivate() {
    super.deactivate();
    print("生命周期:deactivate");
  }

  //state对象从树中被永久移除时调用
  //通常用来回收和释放资源
  @override
  void dispose() {
    super.dispose();
    print("生命周期:dispose");
  }

  //只有热重载时候会调用
  @override
  void reassemble() {
    super.reassemble();
    print("生命周期:reassemble");
  }

  //依赖对象发生变化时被调用
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    print("生命周期:didChangeDependencies");
  }
}

Gets State Widget objects in the tree, and call SnackBar two ways

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "获取State对象",
      home: Scaffold(
        appBar: AppBar(
          title: Text("获取State对象"),
        ),
        body: GetState(),
      ),
    );
  }
}

class GetState extends StatefulWidget {
  @override
  _GetStateState createState() => _GetStateState();
}

class _GetStateState extends State<GetState> {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Column(
          children: <Widget>[
            Builder(
              builder: (context) {
                return RaisedButton(
                  onPressed: () {
                    // 查找父级最近的Scaffold对应的ScaffoldState对象
                    ScaffoldState _scaffoldState =
                    context.ancestorStateOfType(TypeMatcher<ScaffoldState>());
                    //调用ScaffoldState的showSnackBar来弹出SnackBar
                    _scaffoldState.showSnackBar(
                      SnackBar(
                        content: Text("我是SnackBar"),
                      ),
                    );
                  },
                  child: Text("点击显示SnackBar"),
                );
              },
            ),
            Builder(
              builder: (context) {
                return RaisedButton(
                  onPressed: () {
                    // 直接通过of静态方法来获取ScaffoldState
                    ScaffoldState _scaffoldState =
                    Scaffold.of(context);
                    //调用ScaffoldState的showSnackBar来弹出SnackBar
                    _scaffoldState.showSnackBar(
                      SnackBar(
                        content: Text("我是SnackBar"),
                      ),
                    );
                  },
                  child: Text("点击显示SnackBar"),
                );
              },
            ),
          ],
        )
    );
  }
}

By GlobalKeyacquiring Stateobjects

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  //定义
  static GlobalKey<ScaffoldState> _globalKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "获取State对象",
      home: Scaffold(
        key: _globalKey, //设置key
        appBar: AppBar(
          title: Text("获取State对象"),
        ),
        body: Center(
            child: Column(
              children: <Widget>[
                Builder(
                  builder: (context) {
                    return RaisedButton(
                      onPressed: () {
                        // 查找父级最近的Scaffold对应的ScaffoldState对象

                        _globalKey.currentState.openDrawer();


                      },
                      child: Text("点击显示SnackBar"),
                    );
                  },
                ),
              ],
            )),
      ),
    );
  }
}
Published 49 original articles · won praise 6 · views 80000 +

Guess you like

Origin blog.csdn.net/zlhyy666666/article/details/104895842