Flutter setState 改变,但不重新渲染

2024-03-23

我创建了一个简单的屏幕,它接受字母列表并将它们呈现在网格中。我有一个带有随机播放方法的按钮,可以随机播放此列表。在我的构建方法中,我看到状态正在使用新列表进行更新,并且每次按下按钮时都会打印出一个随机列表,但屏幕不会改变。

class _LetterContainerState extends State<LetterContainer> {
  List<String> _letters = ['D', 'A', 'B', 'C', 'E', 'F', 'G', 'H'];



  void shuffle() {
    var random = new Random();
    List<String> newLetters = _letters;
    for (var i = newLetters.length - 1; i > 0; i--) {
      var n = random.nextInt(i + 1);
      var temp = newLetters[i];
      newLetters[i] = newLetters[n];
      newLetters[n] = temp;
    }

    setState(() {
      _letters = newLetters;
    });
  }

  @override
  Widget build(BuildContext context)  {
    print('LETTERS');
    print(_letters);
    List<LetterTile> letterTiles =
        _letters.map<LetterTile>((letter) => new LetterTile(letter)).toList();

    return new Column(
      children: <Widget>[
        new FlatButton(onPressed: shuffle, child: new Text("Shuffle")),
        new Container(

            color: Colors.amberAccent,
            constraints: BoxConstraints.expand(height: 200.0),
            child: new GridView.count(
              crossAxisCount: 4,
              mainAxisSpacing: 4.0,
              crossAxisSpacing: 4.0,
              children: letterTiles,
            ))
      ],
    );
  }
}

EDIT:

import 'package:flutter/material.dart';

class Vowels {
  static const values = ['A', 'E', 'I', 'O', 'U'];

  static bool isVowel(String letter) {
    return values.contains(letter.toUpperCase());
  }
}

class LetterTile extends StatefulWidget {
  final String value;
  final bool isVowel;

  LetterTile(value)
            : value = value,
              isVowel = Vowels.isVowel(value);

  @override
  _LetterTileState createState() => new _LetterTileState(this.value);

}

class _LetterTileState extends State<LetterTile> {
  _LetterTileState(this.value);

  final String value;

  @override
  Widget build(BuildContext context) {
    Color color = Vowels.isVowel(this.value) ? Colors.green : Colors.deepOrange;
    return new
    Card(
      color: color,
      child: Padding(
        padding: EdgeInsets.all(8.0),
        child: Text(
          this.value,
          style: TextStyle(fontSize: 40.0, color: Colors.white)
        )
      )
    );

  }

}

如果您将示例 LetterTile 小部件替换为 Text 小部件,则随机播放将再次进行。这不起作用的原因是状态对象仅在第一次实例化小部件时创建。因此,通过将值直接传递给状态,可以确保它永远不会更新。相反,通过引用该值widget.value:

class LetterTile extends StatefulWidget {
  final String value;
  final bool isVowel;

  LetterTile(this.value) : isVowel = Vowels.isVowel(value);

  @override
  _LetterTileState createState() => new _LetterTileState();
}

class _LetterTileState extends State<LetterTile> { 
  @override
  Widget build(BuildContext context) {
    Color color = Vowels.isVowel(widget.value) ? Colors.green : Colors.deepOrange;
    return Card(
      color: color,
      child: Padding(
        padding: EdgeInsets.all(8.0),
        child: Text(
          widget.value,
          style: TextStyle(fontSize: 40.0, color: Colors.white)
        )
      )
    );
  }
}

编辑:更多解释。

State 对象的要点是它在构建过程中是持久的。第一次构建特定的 LetterTile 小部件时,这还会创建一个新的 State 对象。第二次调用 build 时,框架会找到现有的 State 对象并重用它。这就是如何将计时器、网络请求和其他资源绑定到不可变的小部件树上。

在您的情况下,由于您将字母传递给 State 对象,因此每个字母都将与第一个传递的字母保持关联。相反,通过从小部件中读取它们,当与 State 对象关联的小部件被替换时,您始终会收到最新的数据。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flutter setState 改变,但不重新渲染 的相关文章

  • Android 自定义视图不能以正确的方式处理透明度/alpha

    我正在绘制自定义视图 在此视图中 我使用两个不同的绘画和路径对象在画布上绘画 我基本上是在绘制两个重叠的形状 添加 Alpha 后 视图中重叠的部分比图像的其余部分更暗 这是不希望的 但我不知道如何解决它 这是我的代码片段 用于展示我如何在
  • 毕加索动画加载图像

    我有以下代码在毕加索中加载图像 使用可绘制的占位符在图像下载时显示 不过 我想要的是一个动画旋转进度条样式的旋转器 它可以在图像加载时不断地旋转 就像我在大多数专业应用程序中看到的那样 毕加索似乎不支持这一点 只支持静态图像可绘制 有没有办
  • Retrofit-2 内容类型问题

    我的 Api 接受 Content Type application json 作为标头 我按照改造文档中所述完美设置了标题 Headers Content Type application json POST user classes C
  • 使用 RecyclerView 适配器在运行时更改布局屏幕

    我有两个布局文件 如下所示 如果列表中存在数据 则我显示此布局 当列表为空时 我会显示此布局 现在我想在运行时更改布局 当用户从列表中删除最后一项时 我想将布局更改为第二张图片中显示的 空购物车布局 In getItemCount Recy
  • Android 应用被 Google Play 拒绝

    我最近向 Google Play 商店提交了一个 Android 应用程序 但收到一条消息说我的应用程序已被拒绝 我不确定问题是什么 也找不到确切的解决方案 拒绝原因 违反了禁止行为条款 内容政策 经过定期审核后 我们确定您的应用程序支持
  • 如何从 Retrofit2 获取字符串响应?

    我正在做 android 正在寻找一种方法来执行超级基本的 http GET POST 请求 我不断收到错误 java lang IllegalArgumentException Unable to create converter for
  • 如何在android中设置多个闹钟,在这种情况下最后一个闹钟会覆盖以前的闹钟

    我正在开发一个Android应用程序 用户可以在其中设置提醒时间 但我在以下代码中遇到一个问题 即最后一个警报会覆盖之前的所有警报 MainActivity java public void setreminders DatabaseHan
  • 应用内结算错误

    我的 UNMANAGED 应用内购买无法正常工作 在它完美运行之前 我可以使用测试帐户成功购买 但它突然不起作用了 因为我记得我对商家帐户所做的只是添加更多 2 4 个测试帐户 添加后 我的应用内购买将不起作用 所以我更新了公钥并上传了一个
  • 如何防止布局的方向改变,而不是整个屏幕/活动的方向改变

    我需要一个子布局 可以是任何布局 例如FrameLayout or RelativeLayout 忽略方向变化并始终保持横向 但不是它的父级或任何其他兄弟布局 视图 它们应该相应地改变它们的方向 因此 我不能使用setRequestedOr
  • 如何在进入新活动之前终止线程和处理程序

    大家好 在我尝试清理处理程序时 这段代码可能有点混乱 因为我一直在尝试追踪崩溃发生的位置 我有一个对话框活动 显示密码输入 进度条由线程和处理程序动画显示 似乎当我试图查看进度条是否完成并尝试终止线程时 当我尝试进入新活动时 我这样做的方式
  • Android Studio - 值必须 ≥ 0

    我在 Android Studio 中收到与光标有关的错误 我的代码中有以下行 String data cursor getString cursor getColumnIndex columnIndex columnIndex 被传递到该
  • Flutter:如何在flutter中指定设备id?

    如何在flutter run中选择设备id 请使用 d 标志指定设备 或使用 d all 对所有设备进行操作 iPhone 6 54XXXXXX35130ebefd38f ios iOS 10 3 3 iPhone 7 Plus BA8CX
  • 在为 Android 实现 Google 登录时,任务“:app:transformClassesWithDexForDebug”执行失败

    我正在尝试为 Android 实现 Google 登录 并且我正在按照以下说明进行操作 https developers google com identity sign in android start integrating https
  • 如何在 TextField 中垂直居中不同大小的hintText?

    我有一个TextField像这样 输入文本和提示文本的大小不同 TextField style Theme of context textTheme subhead copyWith fontSize 70 0 decoration Inp
  • Nexus 7 (2013) 和 Win 7 64 - 尽管检查了许多论坛和在线资源,仍无法安装 USB 驱动程序

    我正在尝试设置 Nexus 7 2013 进行调试 但我在安装 USB 驱动程序的步骤中陷入困境 到目前为止 这是我尝试过的 采取的步骤 在 Nexus 7 2013 上打开调试模式 连接设备至 PC 下载 Google USB 驱动程序于
  • NoClassDefFoundError:无法解析:Landroid/support/v7/appcompat/R$styleable

    新手尝试完成 Google 提供的我的第一个应用程序教程 在这个致命异常的过程中 我确实导入了很多随机包来消除许多事情的 无法解析 错误 例如 ActionBarActivity EditText Fragment LayoutInflat
  • 在android中跟踪FTP上传数据?

    我有一个运行 Android 的 FTP 系统 但我希望能够在上传时跟踪字节 这样我就可以在上传过程中更新进度条 安卓可以实现这个功能吗 现在 我正在使用org apache common net ftp我正在使用的代码如下 另外 我在 A
  • Android:解析 XML 数据的最佳解析器 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在开发一个应用程序 其中我第一次要解析来自远程服务器的 xml 文件中的数据 但我无法选择哪个解析器是有效的或最适合解析的 因为我知道主要有
  • Android ScrollView fillViewport 不工作

    我有一个简单的布局 名称位于顶部 按钮位于屏幕底部 或者超出该按钮 以防我添加更多项目 所以我使用带有 LinearLayout 的 ScrollView 如下所示
  • Android 和 Java 中绘制椭圆的区别

    在Java中由于某种原因Ellipse2D Double使用参数 height width x y 当我创建一个RectF在Android中参数是 left top right bottom 所以我对适应差异有点困惑 如果在 Java 中创

随机推荐

  • XSLT 中的序列

    我的 xml 输入是
  • 为 iPod classic 编码视频

    我刚刚安装完ffmpeg在 debian wheezy 上使用这些说明 http trac ffmpeg org wiki UbuntuCompilationGuide http trac ffmpeg org wiki UbuntuCom
  • Lua 中的“加载”有什么作用?

    我试图解决我的理解问题loadLua 脚本中的函数 但没有该命令的任何示例或指南 它在他自己的 Lua 网站上讲述https www lua org manual 5 2 manual html pdf load https www lua
  • 如何在 WPF 中将字符串绑定到 double?

    我想设置一个绑定 问题是目标是 string 类型 但源是 double 类型 在以下代码中 VersionNumber 的类型为 double 当我运行它时 文本块是空的 没有抛出任何异常 我该如何设置这个绑定
  • 使用 cron 防止 Bash 脚本并行或重叠运行

    如果我的 cron 表中有以下条目 00 03 java prog1 sh 00 5 java prog2 sh 第一份工作通常需要 30 分钟左右才能完成 第二项工作大约需要10分钟 在某些特殊情况下 第一份工作需要两个多小时 有没有办法
  • jquery 和 updatepanel?

    我在 ASP NET 中有一个更新面板 可以进行部分页面刷新 我使用 jQuery 取得了一些成功on 方法不过 document ready function 仅在页面初始加载期间调用 而不是在每次 updatepanel 刷新后调用 我
  • 如何在 C++ 调试期间冻结 VSCode 中的线程

    我已经使用 VSCode 进行编码几个月了 真的是太棒了 然而 我发现我无法冻结一个线程 我能做的就是Pause all threads and Continue all threads 如果不冻结特定线程 则很难调试多线程程序 尤其是一些
  • 为什么 v1 Web 组件 customElements.define() 会抛出 TypeError

    我正在使用 v1 Web 组件 根据埃里克 比德尔曼 Eric Bidelman 的说法自定义元素 v1 可重用的 Web 组件 https developers google com web fundamentals primers cu
  • 将常规 Swift 函数转换为 Curry 函数

    我正在尝试将常规函数转换为咖喱函数 但得到Execution was interrupted 下面是我柯里化一个函数并执行 unsafeBitCast 来调用带有一个参数的函数并稍后使用第二个参数调用它的代码 func curry
  • 当“状态”从“打开”更改为“已完成”时,如何将一行移动到工作表(GOOGLE SHEET)的底部

    当 状态 更改为完整时 如何将行移动到同一张纸的底部 我试图找出一旦 Status B 列值从 OPEN 更改为 CLOSED 时如何将行移动到底部 工作表名称为 Sheet1 其中状态下拉菜单位于 B 列 下拉菜单包含 OPEN HOLD
  • libv4l2:打开流时出错:设备上没有剩余空间

    我尝试为 opencv 获取立体声对 我将 Logitech B910 和 Logitech C910 网络摄像头连接到 USB 但有这个错误 我玩弄了怪癖参数并设置outfmt mjpeg在mplayer中 但又出现此错误 在哪里可以找到
  • theano 给出“...正在等待未知进程的现有锁...”

    我的代码运行良好 但是 现在我收到一条错误消息 Using gpu device 0 GeForce GT 750M WARNING theano gof cmodule ModuleCache refresh Found key with
  • Python Pandas 混合布尔 Yes/True 和 NaN 列

    我正在学习健康科学课程 推荐使用 R 或 Stata 我正在尝试使用 Python Numpy Pandas 来代替 因为我希望将来使用它来进行金融时间序列分析 数据是 Stata 格式 所以我复制了字段并将它们保存为CSV 所有字段导入都
  • R Shiny - 多页可编辑数据表在编辑后跳转到第 1 行

    我正在使用 R 3 3 1 Shiny v 1 2 0 和 v DT 0 5 开发一个 Shiny 应用程序 其中一个元素是跨多个页面的可编辑数据表 在我进行编辑后 焦点行会跳转到第 1 行 这会破坏用户体验 以下是使用下面的代码片段重现此
  • 使用 Chrome 将 HTML 填充到 about: URL 中

    以前 在 Internet Explorer 中 您可以在 URL 栏中输入以下内容 about 屏幕会变成红色 Chrome 中是否有等效的 heredoc 语法用于通过 URL 加载 HTML 也许是数据 URI data text h
  • 在 Docker Compose 中执行 /bin/bash

    我正在尝试自动化 docker compose 文件 我想做一些初步任务 例如更新源代码 构建库并自动运行bash只需调用容器上的终端即可docker compose up 有没有办法做到这一点 我尝试执行以下操作 version 3 3
  • KSQL - 删除主题

    有没有办法从 KSQL 中删除该主题 根据github https github com confluentinc ksql blob 4 0 x ksql engine src main java io confluent ksql dd
  • 为什么我无法在 Flutter ModalBottomSheet 中滚动自定义 WebView

    大家好 有人知道为什么我无法在 ModalBottomSheet 中垂直滚动 WebView 吗 这是我的代码 如果有任何问题请告诉我或给我一些建议 showModalBottomSheet context context isScroll
  • 在 Fabric 中作为 sudo 执行

    我有一个命令service app start demo需要我输入sudo service app start demo在命令行中 I used sudo service app start demo and sudo sudo servi
  • Flutter setState 改变,但不重新渲染

    我创建了一个简单的屏幕 它接受字母列表并将它们呈现在网格中 我有一个带有随机播放方法的按钮 可以随机播放此列表 在我的构建方法中 我看到状态正在使用新列表进行更新 并且每次按下按钮时都会打印出一个随机列表 但屏幕不会改变 class Let