Flutter学习笔记13-StatefulWidget控件初体验, 体会关键字const和final的区别

学习视频地址:https://www.bilibili.com/video/BV1S4411E7LY/?p=32&spm_id_from=pageDriver&vd_source=cee744cae4ead27f8193fc7904647073

前一阶段,我们学习的一直是StatelessWidget,无状态组件,从字面意义上看,是相对简单的组件,因为没有状态的变化,初始化后就“死了”,不会再有变动。
本文要学习StatefulWidget,顾名思义,是有状态的组件,状态的变化会改变Widget的显示,Let us learn it!

学习笔记

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primarySwatch: Colors.blue),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _number = 0;
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("flutter demo"),
      ),
      body: Column(
        children: [
          Text(
            "$_number",
            style: Theme.of(context).textTheme.headline1,
          ),
          ElevatedButton(
              onPressed: () {
                setState(() {
                  _number++;
                });
              },
              child: Text("增加"))
        ],
      ),
    );
  }
}

重点看

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  
  _MyHomePageState createState() => _MyHomePageState();
}

StatefulWidget是一个抽象类,想继承它,必须重写它的抽象方法

abstract class StatefulWidget extends Widget {
  /// Initializes [key] for subclasses.
  const StatefulWidget({ Key? key }) : super(key: key);

  /// Creates a [StatefulElement] to manage this widget's location in the tree.
  ///
  /// It is uncommon for subclasses to override this method.
  
  StatefulElement createElement() => StatefulElement(this);

  /// Creates the mutable state for this widget at a given location in the tree.
  ///
  /// Subclasses should override this method to return a newly created
  /// instance of their associated [State] subclass:
  ///
  /// ```dart
  /// @override
  /// _MyState createState() => _MyState();
  /// ```
  ///
  /// The framework can call this method multiple times over the lifetime of
  /// a [StatefulWidget]. For example, if the widget is inserted into the tree
  /// in multiple locations, the framework will create a separate [State] object
  /// for each location. Similarly, if the widget is removed from the tree and
  /// later inserted into the tree again, the framework will call [createState]
  /// again to create a fresh [State] object, simplifying the lifecycle of
  /// [State] objects.
  
  
  State createState(); // ignore: no_logic_in_create_state, this is the original sin
}

抽象方法就是State createState(); 没有方法体,需要子类去自己实现。
这个方法名是创建状态,返回值也是状态。

那我们是如何实现的呢,看下面👇
_MyHomePageState createState() => _MyHomePageState();
相当我们会创建一个_MyHomePageState状态
_MyHomePageState()就是调用了class _MyHomePageState默认的构造方法。
也就是说,我们重写的createState(),就是调用State的构造方法。
createState(创建状态) => State构造😁

_MyHomePageState 是继承自 State 的
State也是个抽象类,需要重写build方法
build方法返回的是一个widget,在widget里写我们想要的布局

class _MyHomePageState extends State<MyHomePage> {
  int _number = 0;
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("flutter demo"),
      ),
      body: Column(
        children: [
          Text(
            "$_number",
            style: Theme.of(context).textTheme.headline1,
          ),
          ElevatedButton(
              onPressed: () {
                setState(() {
                  _number++;
                });
              },
              child: Text("增加"))
        ],
      ),
    );
  }
}

显示效果
在这里插入图片描述
注意按钮中的点击事件:

onPressed: () {
                setState(() {
                  _number++;
                });
              },

是在点击事件内部又调用了setState(),
setState()内部设置了数字自增的逻辑
不调用setState()是没有效果的。

每点击一次setState(),
都会调用一次整个State的build方法
当build内部的子Widget用const 修饰,就不会被重新创建,有利于性能优化

2.给ListView动态添加Item

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primarySwatch: Colors.blue),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> _list = [];
  
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("flutter demo"),
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: () {
            setState(() {
              _list.add("新增一条消息");
            });
          },
        ),
        body: Center(
          child: ListView(
            children: _list.map((value) {
              return ListTile(
                title: Text(value),
              );
            }).toList(),
          ),
        ));
  }
}

看效果
在这里插入图片描述

分析
还是使用StatefulWidget实现
重点看状态类

class _MyHomePageState extends State<MyHomePage> {
  List<String> _list = [];
  
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("flutter demo"),
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: () {
            setState(() {
              _list.add("新增一条消息");
            });
          },
        ),
        body: Center(
          child: ListView(
            children: _list.map((value) {
              return ListTile(
                title: Text(value),
              );
            }).toList(),
          ),
        ));
  }
}

设置了一个悬浮按钮FloatingActionButton

在按钮的点击事件内,会给字符串列表_list添加一条内容 _list.add(“新增一条消息”);

当执行完setState后,会重新执行build,此时_list内容已经被修改过了

所以可以创建新的列表。

3.关键字const和final的区别
const代表常量,常量要在程序运行前就被赋值好,并且程序运行后也不可以修改,常量必须是静态的。(声明就要赋值)

final代表不可修改,final是运行时常量,可以运行时再赋值,只能赋值一次。(可以先声明,再赋值)

final修饰List<> 是可以给List增添元素的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值