文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Flutter中使用setState时的6个简单技巧总结

2024-04-02 19:55

关注

前言

setState 函数是在 Flutter 应用程序中管理状态的最基本方法。以下是一些保持应用可维护性的最佳实践。

StatefulWidget 的 setState 函数是一种在 Flutter 应用程序中管理状态的简单方法。但是,当您希望您的应用程序正常工作和高性能时,您需要避免几个陷阱。以下是您应该坚持的一些最佳实践。

setState 有什么用?

setState 是Flutter发出 rebuild (重建)当前 widget 及其后代的方式。在 rebuild 过程中,最新的变量值将被用于创建用户界面。比方说,一个用户将一个开关从打开切换到关闭。该开关有一个存储该值的支持变量,所以在改变之后,它被设置为 false。开关本身并不反映这一变化,直到它被重建为新的支持字段值。

?技巧 1:保持## widgets小!

setState 触发了对你当前所在的小组件的重建。如果你的整个应用程序只包含一个widget,那么整个widget将被重建,这将使你的应用程序变得缓慢。请看下面的例子。

import 'package:flutter/material.dart';

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

  @override
  State<Home> createState() => _State();
}

class _State extends State<Home> {
  bool _tile1 = false;
  bool _tile2 = false;
  bool _tile3 = false;
  bool _tile4 = false;
  bool _tile5 = false;

  @override
  Widget build(BuildContext context) {
    print("built method Home"); // <-- setState triggers build here!
    return Scaffold(
        appBar: AppBar(title: const Text("Demo")),
        body: Center(
            child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
              SwitchListTile(
                  activeColor: Colors.green,
                  inactiveThumbColor: Colors.red,
                  title: Text("Switch is ${_tile1 ? "on" : "off"}"),
                  value: _tile1,
                  onChanged: (_) {
                    setState(() {
                      _tile1 = !_tile1;
                    });
                  }),
              SwitchListTile(
                  activeColor: Colors.green,
                  inactiveThumbColor: Colors.red,
                  title: Text("Switch is ${_tile2 ? "on" : "off"}"),
                  value: _tile2,
                  onChanged: (_) {
                    setState(() {
                      _tile2 = !_tile2;
                    });
                  }),
              SwitchListTile(
                  activeColor: Colors.green,
                  inactiveThumbColor: Colors.red,
                  title: Text("Switch is ${_tile3 ? "on" : "off"}"),
                  value: _tile3,
                  onChanged: (_) {
                    setState(() {
                      _tile3 = !_tile3;
                    });
                  }),
              SwitchListTile(
                  activeColor: Colors.green,
                  inactiveThumbColor: Colors.red,
                  title: Text("Switch is ${_tile4 ? "on" : "off"}"),
                  value: _tile4,
                  onChanged: (_) {
                    setState(() {
                      _tile4 = !_tile4;
                    });
                  }),
              SwitchListTile(
                  activeColor: Colors.green,
                  inactiveThumbColor: Colors.red,
                  title: Text("Switch is ${_tile5 ? "on" : "off"}"),
                  value: _tile5,
                  onChanged: (_) {
                    setState(() {
                      _tile5 = !_tile5;
                    });
                  })
            ])));
  }
}

这里我们在一个 Column 中有 5 个 SwitchListTile 小部件,它们都是同一个小部件的一部分。

如果您切换任何控件,整个屏幕都会被重建。 Scaffold, AppBar, Column, ... 但只要重建已更改的小部件就足够了。让我们看下一个代码示例:

import 'package:flutter/material.dart';

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

  @override
  State<Home2> createState() => _State();
}

class _State extends State<Home2> {
  @override
  Widget build(BuildContext context) {
    print("built method Home2");
    return Scaffold(
        appBar: AppBar(title: const Text("Demo")),
        body: Center(
            child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                children: const <Widget>[
              Switch(),
              Switch(),
              Switch(),
              Switch(),
              Switch()
            ])));
  }
}

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

  @override
  State<StatefulWidget> createState() => _SwitchState();
}

class _SwitchState extends State<Switch> {
  bool _value = false;

  @override
  Widget build(BuildContext context) {
    print("build method Switch"); // <-- setState triggers build here!
    return SwitchListTile(
        activeColor: Colors.green,
        inactiveThumbColor: Colors.red,
        title: Text("Switch is ${_value ? "on" : "off"}"),
        value: _value,
        onChanged: (_) {
          setState(() {
            _value = !_value;
          });
        });
  }
}

在这里,我们将 SwitchListTile 包装在单个 StatefulWidget 中。页面看起来相同,但如果您单击此示例中的任何开关,则只有单击的小部件将重建。

?技巧 2:不要在构建方法中调用 setState

来自 Flutter API 文档

这个方法有可能在每一帧中被调用,除了建立一个小部件外,不应该有任何副作用。

build 方法旨在构建小部件树,因此我们应该保持这种方式。不要在这里做花哨的事情,它会减慢你的应用程序。对setState的调用可能会触发额外的重建,在最坏的情况下,你可能最终会出现一个异常,告诉你目前有一个重建正在进行。

?技巧 3:不要在 initState 方法中调用 setState

initState 将在完成后触发重建,因此无需在此方法中调用 setState。此方法旨在初始化与状态相关的属性,例如设置默认值或订阅流。不要在这里做任何其他事情!

?技巧4:setState()和setState(...)是相等的

像这样使用 setState 没关系

setState((){
  _text = “Hello”;
});

或者像这样

_text = “Hello”;
setState((){});

结果是一样的。

?技巧 5:setState(...) 代码必须很小

不要在setState内做任何大的计算,因为它将阻止你的应用程序重绘。请看下面的示例代码:

setState(() {
  for (var i = 0; i < 10000; i++) print(i);
  _value = true;
});

只有在打印语句之后,小部件才会重建。在这段时间里,你的应用程序不会对用户的操作做出反应,它将在之后执行这些操作。因此,如果用户因为没有视觉反馈而多次点击一个控件,多次重建就会堆积起来,会使应用程序的速度更慢。

一个更好的方法是在执行一个长期运行的操作时显示一个进度指示器,这样用户就知道正在发生一些事情,他需要等待完成。

?技巧 6:setState(...) 代码不能是异步的

运行代码时

setState(() async {
  await Future.delayed(const Duration(seconds: 5));
});

你最终会得到一个类似这样的异常信息:

在方法之外执行异步操作,然后调用它。

结束

我希望这些见解能帮助你更好地理解Flutter中setState的机制。坚持这些技巧,你会有更少的问题和更快的应用程序。源代码例子可以在GitHub上找到。

到此这篇关于Flutter中使用setState时的6个简单技巧的文章就介绍到这了,更多相关Flutter使用setState的技巧内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯