Почему в следующем коде при нажатии кнопки нельзя вызвать [print («BBB's build function.»)]? - PullRequest
3 голосов
/ 03 августа 2020

Почему в следующем коде при нажатии кнопки нельзя вызвать [print («BBB's build function.»)]? В следующем коде, почему при нажатии кнопки не может быть вызвана [print ("BBB's build function.")]?

  import 'package:flutter/material.dart';

class MyTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: AAA(
            child: BBB(),
          ),
        ),
      ),
    );
  }
}

class AAA extends StatefulWidget {
  AAA({Key key, @required this.child}) : super(key: key);
  final Widget child;

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

class _AAAState extends State<AAA> {
  @override
  Widget build(BuildContext context) {
    print("AAA's build function.");
    return FlatButton(
      onPressed: () {
        setState(() {});
      },
      child: widget.child,
    );
  }
}

class BBB extends StatefulWidget {
  @override
  _BBBState createState() => _BBBState();
}

class _BBBState extends State<BBB> {
  @override
  Widget build(BuildContext context) {
    print("BBB's build function.");
    return Text("text");
  }
}

Ответы [ 3 ]

0 голосов
/ 03 августа 2020

Я считаю, это потому, что Flutter оптимизирует перестройку виджетов. Другими словами, после того, как вы нажмете FlatButton и вызовет setState, Flutter перестроит AAA, потому что вы явно просили об этом (вызвав setState).

После этого Flutter также будет искать, чтобы восстановить все AAA's дети . Но прежде чем это сделать, Flutter достаточно умен, чтобы проверить, стоит ли перестраивать детей AAA. Flutter сравнит существующий виджет BBB с новым виджетом BBB, если он был перестроен. Если они одинаковы, flutter прервет перестройку BBB для экономии ресурсов / оптимизации перестроек.

В вашем случае они такие же. Нет никакой разницы между значением return существующего BBB и нового BBB. Всегда Text("text"). Ваша строка print(bbb...) не возвращается функцией. Он идет перед оператором return .

Ознакомьтесь с этим ответом Реми (создателя пакета Provider) для получения дополнительной информации о topi c.

0 голосов
/ 03 августа 2020

Потому что каждый раз возвращаешь одного и того же ребенка. (который уже построен)

Если вы хотите, чтобы функция сборки вызывалась каждый раз, когда вам нужно использовать LayoutBuilder.

Проверьте мой код с вашим кодом и моими изменениями

Codepen

    import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: MyTest(),
    ),
  );
}

class MyTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: AAA(
            child: (context) => BBB(),
          ),
        ),
      ),
    );
  }
}

class AAA extends StatefulWidget {
  AAA({Key key, @required this.child}) : super(key: key);
  final Widget Function(BuildContext) child;

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

class _AAAState extends State<AAA> {
  @override
  Widget build(BuildContext context) {
    print("AAA's build function.");
    return FlatButton(
        onPressed: () {
          setState(() {});
        },
        child: LayoutBuilder(builder: (context, constrains) => widget.child(context)));
  }
}

class BBB extends StatefulWidget {
  @override
  _BBBState createState() => _BBBState();
}

class _BBBState extends State<BBB> {
  static int p = 0;
  @override
  Widget build(BuildContext context) {
    p++;
    return Text("text$p");
  }
}
0 голосов
/ 03 августа 2020
child: AAA(
 child: BBB(),
 ),

AAA() класс принимает widget в конструкторе, в вашем коде вы передаете виджет BBB(). Когда вы впервые запустите этот код, вы получите:

AAA's build function.
BBB's build function.

Поскольку оба класса собираются. Теперь FlatButton находится внутри класса AAA, когда вы щелкаете по нему, вызывается setState(), а setState() вызывает метод build() класса AAA, таким образом, вы попадаете в консоль при нажатии:

AAA's build function.
...