setState对飞镖/颤振中的对象起作用吗?

时间:2019-12-10 10:21:54

标签: flutter dart

我有一个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确实更新,屏幕上的网格也不会更新。

2 个答案:

答案 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方法中将解决您的问题。由于只有在屏幕/路由初始化时才调用一次。