应用程序是一个简单的记忆/猜谜游戏,带有一个方格。浮动的动作按钮触发“新游戏”对话框,"是"响应触发setState()在主小部件上.打印()调用显示它正在构建网格中的所有Tile小部件,但当它返回时,旧的网格值仍然显示。2可能做了一些愚蠢的事情,但没有看到它。3基本代码如下。4 TIA如果有人可以看到什么是失踪/无效/损坏/等。
dart是创建无状态HomePage的常用main(),它创建使用此State的有状态小部件:
class MemHomePageState extends State<MemHomePage> {
GameBoard gameBoard = GameBoard();
GameController? gameController;
int gameCount = 0, winCount = 0;
@override
void initState() {
super.initState();
gameController = GameController(gameBoard, this);
}
@override
Widget build(BuildContext context) {
if (kDebugMode) {
print("MemHomepageState::build");
}
gameBoard.newGame(); // Resets secrets and grids
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: GridView.count(
crossAxisCount: Globals.num_columns,
children: List.generate(Globals.num_columns * Globals.num_rows, (index) {
int x = index~/Globals.NR, y = index%Globals.NR;
int secret = gameBoard.secretsGrid![x][y];
var t = Tile(x, y, Text('$secret'), gameController!);
gameBoard.tilesGrid![x].add(t);
if (kDebugMode) {
print("Row $x is ${gameBoard.secretsGrid![x]} ${gameBoard.tilesGrid![x][y].secret}");
}
return t;
}),
),
// Text("You have played $gameCount games and won $winCount."),
),
floatingActionButton: FloatingActionButton(
onPressed: () => newGameDialog("Start a new game?"),
tooltip: 'New game?',
child: const Icon(Icons.refresh_outlined),
),
);
}
/** Called from the FAB and also from GameController "won" logic */
void newGameDialog(String message) {
showDialog<void>(
context: context,
barrierDismissible: false, // means the user must tap a button to exit the Alert Dialog
builder: (BuildContext context) {
return AlertDialog(
title: Text("New game?"),
content: Text(message),
//),
actions: <Widget>[
TextButton(
child: const Text('Yes'),
onPressed: () {
setState(() {
gameCount++;
});
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('No'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
}
);
}
Tile类是一个StatefulWidget,其状态决定了特定图块应显示的内容:
import 'package:flutter/material.dart';
import 'gamecontroller.dart';
enum TileMode {
SHOWN,
HIDDEN,
CLEARED,
}
/// Represents one Tile in the game
class Tile extends StatefulWidget {
final int x, y;
final Widget secret;
final GameController gameController;
TileState? tileState;
Tile(this.x, this.y, this.secret, this.gameController, {super.key});
@override
State<Tile> createState() => TileState(x, y, secret);
setCleared() {
tileState!.setCleared();
}
}
class TileState extends State<Tile> {
final int x, y;
final Widget secret;
TileMode tileMode = TileMode.HIDDEN;
TileState(this.x, this.y, this.secret);
_unHide() {
setState(() => tileMode = TileMode.SHOWN);
widget.gameController.clicked(widget);
}
reHide() {
print("rehiding");
setState(() => tileMode = TileMode.HIDDEN);
}
setCleared() {
print("Clearing");
setState(() => tileMode = TileMode.CLEARED);
}
_doNothing() {
//
}
@override
Widget build(BuildContext context) {
switch(tileMode) {
case TileMode.HIDDEN:
return ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.teal,
),
onPressed: _unHide,
child: Text(''));
case TileMode.SHOWN:
return ElevatedButton(
onPressed: _doNothing,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
),
child: secret);
case TileMode.CLEARED:
return ElevatedButton(
onPressed: _doNothing,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.black12,
),
child: const Icon(Icons.check));
}
}
}
2条答案
按热度按时间k3bvogb11#
看起来你在编译函数中调用了下面的函数。2这会导致每次编译时所有的东西都被重置。3也许它属于init?
x7rlezfr2#
最初的问题是Tile对象,虽然正确创建并连接到返回的主部件,但没有明确的'key'值,因此它们没有替换原始对象。UniqueKey()'到循环中的每个Tile(),解决了这个问题。它暴露了一个相关的问题,但超出了这个问题的范围。请查看OP中的github链接以获取最新版本。