dart - 颜色变化时颤动不渲染
问题描述
我是颤振/飞镖的新手。我编写了一个在 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。
解决方案
如此处所述,发生此问题是因为您不遵循不变性原则。
问题的根源在于你的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
推荐阅读
- angular - 垫选择面板打开总是假
- python - 使用 python 将 JSON 文件连接到 GUI 界面
- python - 我如何在 Django ojbect 中舍入一个 Sum
- css - 在 -moz-linear-gradient 内部使用变量会破坏样式
- react-native - 如何过滤 JSON 响应并从中获取所需的数据?
- extjs - ExtJS 7.4(现代工具包),网格标题菜单复选框在选择后无法取消选择(带有过滤器值)
- powershell - 跟踪 RDP 会话的整个历史记录
- c# - 如何在我的 ASP.NET CORE 5 应用程序中清理我的控制器操作和引用?
- java - 调用特定的构造函数来映射@requestBody
- python - 从张量图像(归一化在 0 到 1 之间)到 0 到 255 之间的像素