【问题标题】:flutter not rendering when color changes颜色变化时颤动不渲染
【发布时间】:2019-02-02 06:28:35
【问题描述】:

我是颤振/飞镖的新手。我编写了一个在 GridView 中显示图块的应用程序。每个图块都有编号和颜色,并分配有一个 onTap 处理程序。 onTap 处理程序用于调试打印图块的索引并调用 setState()。 setState() 预计会强制重新渲染 GridView,点击的 tile 显示在 Color.white 中。

在调试模式下执行时,设备上的显示与预期一样。点击磁贴时,调试控制台中会显示 debugPrint 消息,但点击磁贴的颜色不会更改为 Color.white。

我已经检查了重新生成的图块(当一个图块被点击时)。正如预期的那样,所有未开发的图块都被分配了它们的原始图块颜色。轻敲的瓷砖被指定为 Color.white。但是,似乎无法检测到磁贴颜色的变化(即,点击的磁贴颜色从其原始颜色变为 Color.white),并且应用不会使用一个白色磁贴重绘。

应用代码如下。请告知我做错了什么。

// ignore_for_file: camel_case_types
// ignore_for_file: constant_identifier_names
// ignore_for_file: non_constant_identifier_names

import 'package:flutter/material.dart';

const List _normal_colors = [
  Colors.indigo,
  Colors.green,
  Colors.amber,
  Colors.orange,
  Colors.red,
  Colors.blue,
  Colors.cyan,
  Colors.yellow,
  Colors.purple,
]; // _normal_colors

void main() => runApp(new MyApp());

class Tiled_Surface extends StatefulWidget {
  Tiled_Surface({Key key}) : super(key: key);

  @override // Tiled_Surface
  Tiled_Surface_State createState() => Tiled_Surface_State();
}

class Tiled_Surface_State extends State<Tiled_Surface> {
  List<GridTile> _grid_tiles = <GridTile>[];
  int _tapped = -1;

  void on_tile_tapped(int index) {
    debugPrint("You tapped on item $index");
    setState(() {
      _tapped = index;
    });
  } // on_tile_tapped

  GridTile new_surface_tile(Color tile_color, int index) {
    GridTile tile = GridTile(
      child: GestureDetector(
        onTap: () => on_tile_tapped(index),
        child: Container(
          child: Center(
            child: Text (
              index.toString(),
              style: TextStyle(
                fontSize: 24.0,
                color: _tapped == index ?
                           Colors.black :
                           Colors.white,),
            )
          ),
          decoration: BoxDecoration(
            color: _tapped == index ?
                       Colors.white :
                       tile_color,
            shape: BoxShape.rectangle,
          ),
        ),
      )
    );
  return (tile);
  } // new_surface_tile

  List<GridTile> surface_tiles(colors) {
    _grid_tiles.clear();
    for (int i = 0; (i < colors.length); i++) {
      _grid_tiles.add(new_surface_tile(colors[i], i));
    }
    return (_grid_tiles);
  } // surface_tiles

  @override // Tiled_Surface_State
  Widget build(BuildContext context) {
    return GridView.count(
      shrinkWrap: true,
      crossAxisCount: 3,
      childAspectRatio: 1.0,
      padding: const EdgeInsets.all(4.0),
      mainAxisSpacing: 4.0,
      crossAxisSpacing: 4.0,
      children: surface_tiles(_normal_colors),
    );
  }
} // class Tiled_Surface_State

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Widget tiled_surface = Container(
      child: Column(
        children: [
          Tiled_Surface(),
        ],
      ),
    );

    return MaterialApp(
      title: 'Tiled Surface Demo',
      home: Scaffold(
        appBar: AppBar(title: Text('Tiled Surface Demo'),
                       actions: <Widget>[
          IconButton(
            tooltip: "Replay",
            icon: Icon(Icons.replay),
            onPressed: () {
// TODO       _reinitialize_tiles ( );
            },
          ),
        ] ),
        body: Column(
          children: [
            tiled_surface,
          ],
        ),
      ),
    );
  }
}

此问题与推荐答案的不同之处在于,此问题涉及 ListView 的私有类,而此问题涉及 GridView。

【问题讨论】:

  • ListView和GridView是有区别的。我不能只添加一个 GridTile。我尝试添加 _grid_tiles.clear();到 setState() 无济于事。
  • 问题是一样的。您与孩子保持相同的列表实例。 clear 电话就是证明
  • 请告知我如何更改代码。在过去的 4 周里,这一直让人分心。谢谢

标签: dart flutter


【解决方案1】:

正如here 所述,发生此问题是因为您没有遵循不变性原则。

问题的根源在于您的surface_tiles 方法。与其创建新列表,不如重用旧列表。

修复非常简单:

List<GridTile> surface_tiles(colors) {
  _grid_tiles = List<Widget>();
  // push items to grid_tiles

而不是

List<GridTile> surface_tiles(colors) {
  _grid_tiles.clear()
  // push items to grid_tiles

【讨论】:

  • 感谢您的时间和耐心。你的建议奏效了。只有一个问题,行 _grid_tiles = List();需要替换为 _grid_tiles = new List();再次感谢。
  • 另外,你为什么要使用 _grid_tiles 呢?在这种情况下,将其作为成员变量似乎非常不必要,甚至可能很危险......
  • @rmtmckenzie 你提出了一个问题,让我怀疑我是否对颤振/飞镖的渲染方式有正确的认识。你对这方面的好书有什么建议吗?我想我需要阅读它。谢谢
  • 还没有书。你能拥有的最多的是 medium/stackoverflow 或 flutter.io
  • 不幸的是,@Gus Remi 是对的。我建议阅读 Flutter 团队的 technical overview 和 Flutter 文档中的一些教程,尤其是左侧边栏中“更多详细信息”下的项目。
猜你喜欢
  • 2021-07-07
  • 2018-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 2021-10-12
相关资源
最近更新 更多