Flutter 为什么';当父状态在颤振中发生变化时,是否调用子对象的构建方法?

Flutter 为什么';当父状态在颤振中发生变化时,是否调用子对象的构建方法?,flutter,dart,Flutter,Dart,下面是我的代码,我在snake对象上每秒运行move方法,该方法更改snake的状态(snake是一个普通类,只是有一些更新的基本类型),并调用SnakeBoard类的setState。问题是,我希望它调用偶数BoardTile类的build方法,因为它使用了相同的snake对象,该对象在snake对象中发生了更改 由于BoardTile类的构建方法不会在每秒钟调用一次,因此蛇永远不会移动。为什么会这样?请解释一下 class SnakeBoard extends StatefulWidget

下面是我的代码,我在
snake
对象上每秒运行
move
方法,该方法更改snake的状态(snake是一个普通类,只是有一些更新的基本类型),并调用
SnakeBoard
类的
setState
。问题是,我希望它调用偶数
BoardTile
类的
build
方法,因为它使用了相同的
snake
对象,该对象在snake对象中发生了更改

由于BoardTile类的构建方法不会在每秒钟调用一次,因此蛇永远不会移动。为什么会这样?请解释一下

class SnakeBoard extends StatefulWidget {
  List<BoardTile> _boardTiles ;
  List<BoardTile> get boardTiles => _boardTiles;

  set boardTiles(List<BoardTile> boardTiles) {
    _boardTiles = boardTiles;
  }
  Snake _snake ;

  Snake get snake => _snake;

  set snake(Snake snake) {
    _snake = snake;
  }

  SnakeBoard(){
    boardTiles = List.generate( 100 , (int index)=> BoardTile( index , this ) ) ;
    snake = Snake(10 , 10) ;
  }

  @override
  _SnakeBoardState createState() => _SnakeBoardState();
}

class _SnakeBoardState extends State<SnakeBoard> {

  @override
  Widget build(BuildContext context) {
    return Container(
        child : GridView.count(crossAxisCount: 10,
        shrinkWrap: true,
        children: widget.boardTiles
        ),
    );
  }

  @override
  void initState() {
    Timer.periodic(Duration(seconds: 2), (timer){
      setState(() {
        widget.snake.move() ;
        print("Snaking moving !" ) ;
      });
    });
  }
}

class BoardTile extends StatefulWidget {
  final int id ;
  final SnakeBoard snakeBoard ;
  @override
  _BoardTileState createState() => _BoardTileState();

  BoardTile(this.id, this.snakeBoard);
}


class _BoardTileState extends State<BoardTile> {

  @override
  Widget build(BuildContext context) {

    Snake snake = widget.snakeBoard.snake ;
    return Container(
      decoration: BoxDecoration( border: Border.all(width: 1) ),
      child:
      snake.isPresent(widget.id) ? snake.getSnakePartWidget(widget.id)   : Text(widget.id.toString()) ,
    );
  }
}
class SnakeBoard扩展StatefulWidget{
列表(boardTiles);;
列表获取boardTiles=>\u boardTiles;
设置boardTiles(列出boardTiles){
_木板瓷砖=木板瓷砖;
}
蛇(Snake),;
蛇得到蛇=>\u蛇;
设置蛇(蛇){
_蛇=蛇;
}
蛇形板{
boardTiles=List.generate(100,(int-index)=>BoardTile(index,this));
蛇=蛇(10,10);
}
@凌驾
_SnakeBoardState createState()=>U SnakeBoardState();
}
类_蛇板状态扩展状态{
@凌驾
小部件构建(构建上下文){
返回容器(
子项:GridView.count(crossAxisCount:10,
收缩膜:对,
儿童:widget.boardTiles
),
);
}
@凌驾
void initState(){
定时器。周期(持续时间(秒:2),(定时器){
设置状态(){
widget.snake.move();
打印(“蛇行移动!”);
});
});
}
}
类BoardTile扩展StatefulWidget{
最终int id;
最终蛇形板蛇形板;
@凌驾
_BoardTileState createState()=>\u BoardTileState();
BoardTile(this.id,this.snakeBoard);
}
类(扩展状态){
@凌驾
小部件构建(构建上下文){
Snake Snake=widget.snakeBoard.Snake;
返回容器(
装饰:框装饰(边框:border.all(宽度:1)),
儿童:
snake.isPresent(widget.id)?snake.getSnakePartWidget(widget.id):文本(widget.id.toString()),
);
}
}

在不运行代码的情况下,我的一般建议是尝试将构成“状态”(此处为
Snake
)的字段/属性从
SnakeBoard
移动到
\u SnakeBoardState

为了具体回答你的问题:

Flatter不重建
BoardTile
s(而是重用旧的)是合理的,因为snake不是
BoardTile
s'状态的一部分——因此它需要是
\u BoardTileEstate
类中的一个字段。
因此,从Flatter的角度来看,
BoardTile
的状态没有改变。

您应该在BoardTile类的构建方法中调用setState,而不是initState方法SnakeBoard类