1.4 Splash 倒计时

目标

  • 使用有状态组件
  • 倒计时更新组件
image-20220622152436445

改成有状态组件

lib/pages/splash.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import '../common/index.dart';

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

  
  State<SplashPage> createState() => _SplashPageState();
}

class _SplashPageState extends State<SplashPage> {
  // 图标
  Widget _buildLogo() {
    return Stack(
      alignment: Alignment.center,
      children: [
        // 底部
        Container(
          width: 120,
          height: 120,
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(120 / 2),
          ),
        ),
        // 图标
        Image.asset(
          AssetsImages.logoPng,
          width: 84,
          height: 80,
        ),
      ],
    );
  }

  // 主视图
  Widget _buildView(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        // 图标
        _buildLogo(),

        const SizedBox(height: 24),

        // 标题
        const Text(
          "Online Market",
          style: TextStyle(
            fontSize: 19,
            fontFamily: "Poppins",
            fontWeight: FontWeight.bold,
            color: Colors.white,
            height: 22 / 19,
          ),
        ),

        const SizedBox(height: 27),

        // 倒计时
        Text(
          "0",
          style: const TextStyle(
            fontSize: 19,
            fontFamily: "Poppins",
            fontWeight: FontWeight.bold,
            color: Colors.white,
            height: 22 / 19,
          ),
        ),
      ],
    );
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColors.backgroundSplash,
      body: Center(child: _buildView(context)),
    );
  }
}

实现倒计时

lib/pages/splash.dart

  • 计数 num
  // 计数 num
  final duration = 10;
  int number = 0;
  • 倒计时函数
  // 倒计时
  Future<void> _countdown() async {
    number = duration;
    for (int i = 0; i < duration; i++) {
      await Future.delayed(const Duration(seconds: 1), () {
        if(mounted == ture) {
          setState(() {
            number--;
          });
        }
      });
      // 倒计时结束, 进入 welcome
      if (number == 0) {
        if (kDebugMode) {
          print("倒计时结束");
        }
      }
    }
  }

注意 await async 异步函数的语法

  • 初始执行
  
  void initState() {
    super.initState();
    _countdown();
  }
  • 打印显示
  // 主视图
  Widget _buildView(BuildContext context) {
    		...

				// 倒计时
        Text(
          number > 0 ? "$number" : "done",
          style: const TextStyle(
            fontSize: 19,
            fontFamily: "Poppins",
            fontWeight: FontWeight.bold,
            color: Colors.white,
            height: 22 / 19,
          ),
        ),

重构文字显示函数

macos 下是 option + enter , 也可以在组件上 右键 -> 重构...

image-20220702124930312

文字显示函数

  // 文字显示
  Text _buildText(String text) {
    return Text(
      text,
      style: const TextStyle(
        fontSize: 19,
        fontFamily: "Poppins",
        fontWeight: FontWeight.bold,
        color: Colors.white,
        height: 22 / 19,
      ),
    );
  }

主视图代码

  // 主视图
  Widget _buildView(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          // logo
          _buildLogo(),
          const SizedBox(height: 24),

          // 标题
          _buildText("Online Market"),
          const SizedBox(height: 27),

          // 计数器
          _buildText("10"),

          // end
        ],
      ),
    );
  }

完整代码

lib/pages/splash.dart

import 'package:flutter/material.dart';

import '../common/app_colors.dart';
import '../common/assets.dart';

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

  
  State<SplashPage> createState() => _SplashPageState();
}

class _SplashPageState extends State<SplashPage> {
  // 计数变量
  final duration = 3;
  int number = 0;

  // 倒计时函数
  Future<void> _countdown() async {
    number = duration;
    for (var i = 0; i < duration; i++) {
      await Future.delayed(const Duration(seconds: 1), () {
        if (mounted == true) {
          setState(() {
            number--;
          });
        }
      });

      if (number == 0) {
        print("倒计时结束");
      }
    }
  }

  
  void initState() {
    super.initState();
    _countdown();
  }

  // logo
  Widget _buildLogo() {
    return Stack(
      alignment: Alignment.center,
      children: [
        // 底部
        Container(
          width: 120,
          height: 120,
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(120 / 2),
          ),
        ),

        // 图片
        Image.asset(
          AssetsImages.logoPng,
          width: 84,
          height: 80,
        ),
      ],
    );
  }

  // 文字显示
  Text _buildText(String text) {
    return Text(
      text,
      style: const TextStyle(
        fontSize: 19,
        fontFamily: "Poppins",
        fontWeight: FontWeight.bold,
        color: Colors.white,
        height: 22 / 19,
      ),
    );
  }

  // 主视图
  Widget _buildView(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          // logo
          _buildLogo(),
          const SizedBox(height: 24),

          // 标题
          _buildText("Online Market"),
          const SizedBox(height: 27),

          // 计数器
          _buildText(number > 0 ? "$number" : "done"),

          // end
        ],
      ),
    );
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColors.backgroundSplash,
      body: _buildView(context),
    );
  }
}

总结

  • 无状态组件重构成有状态组件
  • 使用 Future.delayed 方式实现倒计时
  • 使用 三目运算符 控制显示
Last Updated:
Contributors: ducafecat