首页 > 解决方案 > 颜色变化时颤动不渲染

问题描述

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

在调试模式下执行时,设备上的显示与预期一样。当一个磁贴被点击时,debugPrint 消息会显示在 DEBUG CONSOLE 中,但是被点击的磁贴的颜色不会变为 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。

标签: dartflutter

解决方案


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

问题的根源在于你的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

推荐阅读