初识StatefulWidget

改写计数器

flutter初始自带的main函数是实现一个计数器,但对初学者来说比较难,所以我们来改写一个新的简单的计数器,在这个过程中体会statefulWidget的应用。

这个计数器的最终实现效果如下(chrome运行的结果)。主要功能是点击+/-按钮对应的计数会发生变化。

首先最基本的,与与原始的main函数一样,要使用statefulWidget或StatelessWidget,我们需要导入material.dart

dart 复制代码
import 'package:flutter/material.dart'

dart的入口是main函数,所以我们需要写一个main函数入口。main函数中调用runApp来运行MyApp。ps. 用vscode的话,输入main就会自动生成标准main函数。

dart 复制代码
void main(List<String> args) {
  runApp(MyApp());
}

接下来我们就需要实现MyApp了。MyApp是整个计数器程序的主体部分,主要实现首页的导航栏(1)和首页的主体(2)两部分。

MyApp 因为内部不会有状态改变,所以继承自StatelessWidget,并且需要重写build函数。

build里返回一个MaterialApp,这里由于我们只有一页内容,所以只需要实现主页,也就是home参数。home参数的值调用Scaffold,这个实现了一些常用的结构,我们需要用到appBar和body两个参数,对应导航栏和主体。导航栏的工作比较简单,就是加了个标题,用title参数,传入一个文本widget,Text。

主体部分是一个计数器,为了避免嵌套太多,把这部分抽出来,用一个statefulWidget实现其功能。

dart 复制代码
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("计数器", TextStyle(fontSize: 36),)
        ),
        body: MyCounterWidget(),
      )
    );
  }
}

实现MyCounterWidget。statefulWidget还需要实现一个state类,用于存储状态的改变。statefulWidget类需要重写createState,并返回对应的State类。而State类需要重写build函数,里面是计数器的主体部分。

这里counter是维护计数的变量,由于计数器居中,函数返回一个Center,里面包裹一个Column。Columns的参数mainAxisAlignment表示主轴对齐,对Column来说主轴就是垂直方向的轴,mainAxisAlignment.center表示沿主轴居中。Column的参数children表示里面装的内容,这里分为两部分,上面的计数按钮,和下面的计数值。

计数按钮又用分为左右两部分,用Row包裹。要实现按钮功能,用ElevatedButton组件。为了识别计数变化并更新显示结果,需要给ElecatedButton的参数onPressed传入setState函数,当counter变化时,setState将改变元素状态使build函数重建,从而完成更新。

dart 复制代码
class MyCounterWidget entends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return MyCounterState();
  }
}

class MyCounterState extends State<MyCounterWidget> {
  int counter = 0;
  
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: mainAxisAlignment.center,
        children: <Widget>[
          Row(
            mainAxisAlignment:mainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                child: Text(
                  "+1",
                  style: TextStyle(fontSize: 18, color: Colors.white),
                ),
                onPressed: () {
                  setState(() {
                    counter++;
                  });
                },
              ),
              ElevatedButton(
                child: Text(
                  "-1",
                  style: TextStyle(fontSize: 18, color: Colors.white),
                ),
                onPressed: () {
                  setState(() {
                    counter--;
                  });
                },
              ),
            ],
          ),
          Text(
            "当前计数:$counter",
            style: TextStyle(fontSize: 30),
          ),
        ],
      )
    );
  }
}

一个简单计数功能的小程序就完成啦!

声明:本篇文章参考自coderwhy flutter系列教程mp.weixin.qq.com/s?__biz=Mzg...

相关推荐
东风破_2 小时前
React 受控组件与非受控组件:从一个输入框讲清表单数据流
前端
尤乐娃子2 小时前
进入大厂(厂子大)实习Day12
前端·笔记·实习
程序员爱钓鱼2 小时前
Rust Copy详解:隐式复制与轻量数据类型
前端·后端·rust
四六的六4 小时前
端侧模型多端部署实战:从格式转换到灰度发布,Web 和移动端统一部署流水线
前端·人工智能·大模型·ai编程·ai模型·ai产品·端侧ai
独隅6 小时前
前端离线暂停更新策略:Service Worker 与 PWA 的静默控制实践
前端
妙码生花6 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(五十八):后台系统配置管理实现
前端·后端·go
用户938515635076 小时前
React 受控/非受控组件与 React.memo 性能优化——从本质到实战
前端·javascript·react.js
IT_陈寒6 小时前
Java并行流把我坑惨了:原来不是线程安全的!
前端·人工智能·后端
计科土狗7 小时前
GESP六级专题之类与对象
java·前端·数据库