小组件, 在Flutter中, 万物皆组件
Widget是抽象类

1 StatelessWidget

没有状态改变的Widget,通常这种Widget仅仅是做一些展示工作
StatelessWidget包含一个必须重写的方法:build方法;

build方法的解析:

  • Flutter在拿到我们自己创建的StatelessWidget时,就会执行它的build方法;
  • 我们需要在build方法中告诉Flutter,我们的Widget希望渲染什么元素,比如一个Text Widget;
  • StatelessWidget没办法主动去执行build方法,当我们使用的数据发生改变时,build方法会被重新执行;

build方法什么情况下被执行呢?:

  • 当我们的StatelessWidget第一次被插入到Widget树中时(也就是第一次被创建时);
  • 当我们的父Widget(parent widget)发生改变时,子Widget会被重新构建;
  • 如果我们的Widget依赖InheritedWidget的一些数据,InheritedWidget数据发生改变时;
    1. class MyStatelessWidget extends StatelessWidget {
    2. @override
    3. Widget build(BuildContext context) {
    4. return <返回我们的Widget要渲染的Widget,比如一个Text Widget>;
    5. }
    6. }

    (1) 代码示例

    ```dart import ‘package:flutter/material.dart’;

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

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: HYHomeBody() ); } }

class HYHomeBody extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(“第一个Flutter程序”), ), body: const Center( child: Text( “Hello World”, textDirection: TextDirection.ltr, style: TextStyle( fontSize: 30, color: Colors.orange, ), ), ), ); } }

  1. <a name="LWFhV"></a>
  2. # 2 StatefulWidget
  3. 需要保存状态,并且可能出现状态改变的Widget;<br />因为在Flutter中,只要数据改变了Widget就需要重新构建(rebuild)<br />使用State类就可以使用局部刷新
  4. <a name="FHBWr"></a>
  5. ## (1) 代码示例
  6. ```dart
  7. import 'package:flutter/material.dart';
  8. void main() => runApp(MyApp());
  9. class MyApp extends StatelessWidget {
  10. @override
  11. Widget build(BuildContext context) {
  12. return MaterialApp(
  13. debugShowCheckedModeBanner: false,
  14. home: Scaffold(body: HYHomeBody())
  15. );
  16. }
  17. }
  18. class HomeBody extends StatefulWidget {
  19. @override
  20. State<StatefulWidget> createState() {
  21. return HomeBodyState();
  22. }
  23. }
  24. class HomeBodyState extends State<HomeBody> {
  25. var flag = true;
  26. @override
  27. Widget build(BuildContext context) {
  28. return Center(
  29. child: Row(
  30. mainAxisAlignment: MainAxisAlignment.center,
  31. children: <Widget>[
  32. Checkbox(
  33. value: flag,
  34. onChanged: (value) {
  35. flag = value!;
  36. }),
  37. Text("同意协议", style: TextStyle(fontSize: 20))
  38. ],
  39. ),
  40. );
  41. }
  42. }

(2) 生命周期

StatefulWidget本身由两个类组成的:StatefulWidget和State
image.png

  • initState:
    • 会在这个方法中执行一些数据初始化的操作
  • didChangeDependencies:
    • 情况一:调用initState时会调用;
    • 情况二:从其他对象中依赖一些数据发生改变时,比如前面我们提到的InheritedWidget(这个后面会讲到);
  • didUpdateWidget:
    • 当父Widget触发重建(rebuild)时,系统会调用didUpdateWidget方法 ```dart import ‘package:flutter/material.dart’;

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

class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key);

@override Widget build(BuildContext context) { return MaterialApp( home: HomePage(), ); } }

class HomePage extends StatelessWidget { HomePage() { print(“call HomePage”); }

@override Widget build(BuildContext context) { print(“call HomePage build”); return Scaffold( appBar: AppBar( title: Text(“商品列表”), ), body: HomeContent(), ); } }

class HomeContent extends StatefulWidget { HomeContent() { print(“call HomeContent”); }

@override _HomeContentState createState() { print(“call createState”); return _HomeContentState(); } }

class _HomeContentState extends State { int _counter = 0;

_HomeContentState() { print(“call _HomeContentState”); }

@override initState() { print(“call initState”); return super.initState(); }

@override Widget build(BuildContext context) { print(“call _HomeContentState build”);

  1. return Center(
  2. child: Column(
  3. children: [
  4. _getButtons(),
  5. Text(
  6. "当前计数: $_counter",
  7. style: TextStyle(fontSize: 25),
  8. )
  9. ],
  10. ),
  11. );

}

Widget _getButtons() { return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () { setState(() { _counter++; }); }, child: Text( “+”, style: TextStyle(fontSize: 20, color: Colors.white), ), style: ButtonStyle( backgroundColor: MaterialStateColor.resolveWith((states) => Colors.pink)), ), ElevatedButton( onPressed: () { setState(() { _counter—; }); }, child: Text(“-“), style: ButtonStyle( backgroundColor: MaterialStateColor.resolveWith((states) => Colors.purple)), ), ], ); } }

```