我认为我的应用设计错误。我不熟悉Flutter / Dart,并且发现自己对以前使用其他语言(特别是C#和JavaScript)的经验感到困惑。
我有一个应用程序,当前由3个3色GridView和9个彩色圆形瓷砖组成,名为Tiled_Surface。每个图块都分配了以下onTap处理程序:
void on_tile_tapped(int index) {
setState(() {
tile_tapped = index;
});
} // on_tile_tapped
其中索引具有[0..8)范围内的任意值。每当轻敲图块时,图块的颜色都会更改为较浅的值(实际上是图块颜色的“强调颜色”)。所有的工作文件。
AppBar包含一个标题(“ Tiled Surface Demo”)和两个由两个IconButton组成的动作(Icons.swap_horiz和Icons.replay)。意图是,当轻按交换图标时,磁贴颜色会随机排列为新的随机顺序。轻按“重播”图标后,图块颜色将恢复为其原始顺序。轻按两个AppBar图标后,直到轻按磁贴,显示才会发生明显变化。然后,将显示由AppBar水龙头进行的更改。
这不是理想的效果。我的问题是在点按AppBar图标时如何呈现Tiled_Surface。
该应用的代码如下。感谢您的想法。
// ignore_for_file: camel_case_types
// ignore_for_file: constant_identifier_names
// ignore_for_file: non_constant_identifier_names
import 'package:flutter/material.dart';
import 'dart:math';
const int NUMBER_TILES = 9;
final int cross_axis_count = (sqrt (NUMBER_TILES)).toInt();
final double cross_axis_spacing = 4.0;
final double main_axis_spacing = cross_axis_spacing;
List<int> indices = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ];
List normal_colors = [
Colors.red,
Colors.orange,
Colors.yellow,
Colors.green,
Colors.blue,
Colors.purple,
Colors.amber,
Colors.cyan,
Colors.indigo,
]; // normal_colors
List bright_colors = [
Colors.pinkAccent,
Colors.orangeAccent,
Colors.yellowAccent,
Colors.lightGreenAccent,
Colors.blue.shade200,
Colors.purpleAccent,
Colors.amberAccent,
Colors.cyanAccent,
Colors.indigoAccent,
]; // bright_colors
void reinitialize_tiles() {
indices.clear();
for (int i = 0; (i < NUMBER_TILES); i++) {
indices.add(i);
}
} // reinitialize_tiles
void randomize_tiles() {
var random = new Random();
indices.clear();
for (int i = 0; (i < NUMBER_TILES); i++) {
var varient = random.nextInt(9);
if (indices.length > 0) {
while (indices.contains(varient)) {
varient = random.nextInt(9);
}
}
indices.add(varient);
}
} // randomize_tiles
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 tile_tapped = -1;
void on_tile_tapped(int index) {
setState(() {
tile_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(
decoration: BoxDecoration(
color: tile_color,
shape: BoxShape.circle,
),
),
)
);
return (tile);
} // new_surface_tile
List<GridTile> create_surface_tiles() {
grid_tiles = new List<GridTile>();
for (int i = 0; (i < NUMBER_TILES); i++) {
Color tile_color = ( tile_tapped == i ) ?
bright_colors[indices[i]] :
normal_colors[indices[i]];
grid_tiles.add(new_surface_tile(tile_color, i));
}
return (grid_tiles);
} // create_surface_tiles
@override // Tiled_Surface_State
Widget build(BuildContext context) {
return GridView.count(
shrinkWrap: true,
crossAxisCount: cross_axis_count,
childAspectRatio: 1.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: main_axis_spacing,
crossAxisSpacing: cross_axis_spacing,
children: create_surface_tiles(),
);
}
} // class Tiled_Surface_State
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Tiled Surface Demo',
home: Scaffold(
appBar: AppBar(
title: Text('Tiled Surface Demo'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.swap_horiz),
onPressed: () {
randomize_tiles();
},
),
IconButton(
icon: Icon(Icons.replay),
onPressed: () {
reinitialize_tiles();
},
)
]
),
body: Column(
children: [
Tiled_Surface(),
],
),
),
);
}
}
答案 0 :(得分:0)
问题:
Flutter小部件(有状态)将仅对状态变量做出反应。不适用于全球和本地。在您的示例中,indices
是全局变量。
我使用以下代码更新了代码
indices
移动为MyApp
MyApp
反映索引中的更改 MyApp
开始持有state
时将其更改为StatefulWidget
randomize_tiles
和reinitialize_tiles
移动到_MyAppState
并在setState
更改时添加indices
,以便小部件将获得re-rendered
。Tiled_Surface
也需要索引,因此injecting
(在构造函数中传递它们)。请看看
import 'package:flutter/material.dart';
import 'dart:math';
const int NUMBER_TILES = 9;
final int cross_axis_count = (sqrt(NUMBER_TILES)).toInt();
final double cross_axis_spacing = 4.0;
final double main_axis_spacing = cross_axis_spacing;
List normal_colors = [
Colors.red,
Colors.orange,
Colors.yellow,
Colors.green,
Colors.blue,
Colors.purple,
Colors.amber,
Colors.cyan,
Colors.indigo,
]; // normal_colors
List bright_colors = [
Colors.pinkAccent,
Colors.orangeAccent,
Colors.yellowAccent,
Colors.lightGreenAccent,
Colors.blue.shade200,
Colors.purpleAccent,
Colors.amberAccent,
Colors.cyanAccent,
Colors.indigoAccent,
]; // bright_colors
void main() => runApp(new MyApp());
class Tiled_Surface extends StatefulWidget {
List<int> indices;
Tiled_Surface(this.indices, {Key key}) : super(key: key);
@override // Tiled_Surface
Tiled_Surface_State createState() => Tiled_Surface_State(indices);
}
class Tiled_Surface_State extends State<Tiled_Surface> {
List<GridTile> grid_tiles = <GridTile>[];
int tile_tapped = -1;
List<int> indices;
Tiled_Surface_State(this.indices);
void on_tile_tapped(int index) {
setState(() {
tile_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(
decoration: BoxDecoration(
color: tile_color,
shape: BoxShape.circle,
),
),
));
return (tile);
} // new_surface_tile
List<GridTile> create_surface_tiles() {
grid_tiles = new List<GridTile>();
for (int i = 0; (i < NUMBER_TILES); i++) {
Color tile_color = (tile_tapped == i)
? bright_colors[indices[i]]
: normal_colors[indices[i]];
grid_tiles.add(new_surface_tile(tile_color, i));
}
return (grid_tiles);
} // create_surface_tiles
@override // Tiled_Surface_State
Widget build(BuildContext context) {
return GridView.count(
shrinkWrap: true,
crossAxisCount: cross_axis_count,
childAspectRatio: 1.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: main_axis_spacing,
crossAxisSpacing: cross_axis_spacing,
children: create_surface_tiles(),
);
}
} // class Tiled_Surface_State
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
List<int> indices = [0, 1, 2, 3, 4, 5, 6, 7, 8];
void randomize_tiles() {
var random = new Random();
indices.clear();
for (int i = 0; (i < NUMBER_TILES); i++) {
var varient = random.nextInt(9);
if (indices.length > 0) {
while (indices.contains(varient)) {
varient = random.nextInt(9);
}
}
indices.add(varient);
}
setState(() {});
}
void reinitialize_tiles() {
indices.clear();
for (int i = 0; (i < NUMBER_TILES); i++) {
indices.add(i);
}
setState(() {});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Tiled Surface Demo',
home: Scaffold(
appBar: AppBar(title: Text('Tiled Surface Demo'), actions: <Widget>[
IconButton(
icon: Icon(Icons.swap_horiz),
onPressed: () {
randomize_tiles();
},
),
IconButton(
icon: Icon(Icons.replay),
onPressed: () {
reinitialize_tiles();
},
)
]),
body: Column(
children: [
Tiled_Surface(indices),
],
),
),
);
}
}