我有一个Flutter小部件,试图解决soduku网格。我有一个名为SodukuSolver
的类,它可以进行所有计算并提供当前结果的List<String>
。我致电setState
刷新列表,但它不会更新屏幕。
下面,我将尝试包括尽可能多的相关代码。全文见https://github.com/mankowitz/soduku
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(title: "Soduku solver", home: Soduku());
}
}
class SodukuState extends State<Soduku> {
SodukuSolver ss;
List<String> _list;
int _changes = 0;
int _remaining = 81;
@override
Widget build(BuildContext context) {
final String _starting =
"750943002024005090300020000140089005093050170500360024000070009070400810400198057";
ss = new SodukuSolver(_starting);
_list = ss.getList();
return Scaffold(
appBar: AppBar(title: Text('Soduku solver'), actions: <Widget>[
// action button
IconButton(
icon: Icon(Icons.directions_walk),
onPressed: () {
_iterate();
},
),
]),
body: _buildGrid(),
);
}
Widget _buildGrid() {
return Column(children: <Widget>[
AspectRatio(
aspectRatio: 1.0,
child: Container(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 9,
),
itemBuilder: _buildGridItems,
itemCount: 81,
),
),
),
]);
}
Widget _buildGridItems(BuildContext context, int index) {
return GestureDetector(
child: GridTile(
child: Container(
child: Center(
child: Text(_list[index]),
),
),
),
);
}
void _iterate() {
setState(() {
_changes = ss.iterateSoduku();
_remaining = ss.empties();
_list = ss.getList();
});
}
}
class Soduku extends StatefulWidget {
@override
SodukuState createState() => SodukuState();
}
因此,问题在于正在调用_iterate()
,并且我可以使用调试器查看SodukuSolver
的内部状态是否正在更新,甚至可以正确地传递_list
,但是即使_changes
和_remaining
确实更新,屏幕上的网格也不会更新。
答案 0 :(得分:1)
每次构建小部件时,您都会使用相同的base_path(); // '/var/www/mysite'
app_path(); // '/var/www/mysite/app'
storage_path(); // '/var/www/mysite/storage'
创建新的SodukuSolver
,然后从中获取_starting
。因此,您将覆盖先前迭代中的更改。
看来_list
的创建应该执行一次。您可以在SodukuSolver
中覆盖initState
并在其中初始化SodukuState
或在声明它的相同位置对其进行初始化
答案 1 :(得分:1)
只需将代码添加到initState()方法中,如下所示
@override
void initState() {
super.initState();
final String _starting =
"750943002024005090300020000140089005093050170500360024000070009070400810400198057";
ss = new SodukuSolver(_starting);
_list = ss.getList();
}
在您的情况下,您的列表没有更新,因为setState()方法将调用您的SodukuSolver()和ss.getList();。每次的方法。因为setSate()最终每次都会调用build方法进行渲染。
因此将其添加到您的initState方法中将解决您的问题。由于只有在屏幕/路由初始化时才调用一次。