Says flutter---04StatelessWidget和StatefulWidget

194 阅读3分钟

StatelessWidget(商品列表)

  • 案例代码
import 'package:flutter/material.dart';
main()=>runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HYHomePage(),
    );
  }
}
class HYHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('商品列表'),
      ),
      body: HYHomeContent(),
    );
  }
}
class HYHomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        HYHomeContentItem('dsf','aaa',
        'https://tva1.sinaimg.cn/large/006y8mN6gy1g72j6nk1d4j30u00k0n0j.jpg'),
        SizedBox(height: 10),
       HYHomeContentItem('aaa','ccc',
       'https://tva1.sinaimg.cn/large/006y8mN6gy1g72imm9u5zj30u00k0adf.jpg'),
        SizedBox(height: 10),
        HYHomeContentItem('ddd','xxx',
        'https://tva1.sinaimg.cn/large/006y8mN6gy1g72imqlouhj30u00k00v0.jpg'),
      ],
    );
  }
}
class HYHomeContentItem extends StatelessWidget {
  final String title;
  final String desc;
  final String imgUrl;
  //final变量必须初始化
  HYHomeContentItem(this.title,this.desc,this.imgUrl);
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(12),
      decoration: BoxDecoration(
          border: Border.all(color: Colors.pink,width: 5)
      ),
      child: Column(
        children: <Widget>[
          Text(title,style: TextStyle(fontSize: 20)),
          SizedBox(height: 5),
          Text(desc,style: TextStyle(fontSize: 16)),
          SizedBox(height: 5),
          Image.network(imgUrl)
        ],
      ),
    );
  }
}
  • 代码解析
    1.ListView()使得Column(适用于上下布局的元素)成为可滚动的区域;
    2.Container()包裹某一个Column()使得有宽、高、边框、内外边距等。
    

StatefulWidget(简易计数器)

  • 为什么flutter设计StatefulWidget的build方法不在Widget里面,而是在State里面?
    1.build出来的Widget是需要依赖State中的变量(状态/数据);
    2.在flutter的运行过程中,Widget是不断销毁和创建的;当我们自己的状态发生改变时,并不希望重新状态一个新的State。
    
  • 综合案例
    import 'package:flutter/material.dart';
    main()=>runApp(MyApp());
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: HYHomePage(),
        );
      }
    }
    class HYHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('flutter')),
          body: HYHomeContent('你好啊,aaa'),
        );
      }
    }
    class  HYHomeContent extends StatefulWidget {
      final String mes;
      HYHomeContent(this.mes);
      @override
      State<StatefulWidget> createState() {
        // TODO: implement createState
        return _HYContentBodyState();
      }
    }
    class _HYContentBodyState extends State<HYHomeContent>{
    
      int _count=0;
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  RaisedButton(
                    color: Colors.red,
                    child: Text('+',style: TextStyle(fontSize: 20,color: Colors.white)),
                    onPressed: (){
                      setState(() {
                        _count++;
                      });
                    },
                  ),
                  RaisedButton(
                    color: Colors.pink,
                    child: Text('-',style: TextStyle(fontSize: 30,color: Colors.white)),
                    onPressed: (){
                      setState(() {
                        _count--;
                      });
                    },
                  )
                ],
              ),
              Text('当前计数: $_count',style: TextStyle(fontSize: 20)),
              Text('传递过来的信息:${widget.mes}')
            ],
          ),
        );
      }
    }
    1.StatelessWidget从父类传值直接传就可以;StatefulWidget从父类传值可以一个参数一个参数传递,也可以在State中通过widget.参数获取(State类里面有一个widget属性,可直接通过该属性获取参数);
    2.StatefulWidget必须实现createState方法,在State中通过setState改变数据状态。
    

生命周期

  • StatelessWidget
    先执行构造函数,然后执行build方法。
    
  • StatefulWidget
    我们知道StatefulWidget本身由两个类组成的:StatefulWidget和State,分开进行分析:
    首先,执行StatefulWidget中相关的方法:
    	1、执行StatefulWidget的构造函数(Constructor)来创建出StatefulWidget;
    	2、执行StatefulWidget的createState方法,来创建一个维护StatefulWidget的State对象;
    其次,调用createState创建State对象时,执行State类的相关方法:
    	1、执行State类的构造方法(Constructor)来创建State对象;
    	2、执行initState,我们通常会在这个方法中执行一些数据初始化的操作,或者也可能会发送网络请求;
    	(这个方法是重写父类的方法,必须调用super,因为父类中会进行一些其他操作;源码会有一个注解@mustCallSuper3、执行didChangeDependencies方法,这个方法在两种情况下会调用:
    	(调用initState会调用)
      (从其他对象中依赖一些数据发生改变时,比如前面我们提到的InheritedWidget)
      4、Flutter执行build方法,来看一下我们当前的Widget需要渲染哪些Widget;
    	5、当前的Widget不再使用时,会调用dispose进行销毁;
    	6、手动调用setState方法,会根据最新的状态(数据)来重新调用build方法,构建对应的Widgets;
    	7、执行didUpdateWidget方法是在当父Widget触发重建(rebuild)时,系统会调用didUpdateWidget方法;
    

flutter的编程范式

声明式编程(依靠自己自动进行状态管理,而不是手动更新)