Flutter Provider перестраивает виджет по назначению страницы - PullRequest
0 голосов
/ 24 марта 2020

Я просто узнаю о провайдере и создаю демо-версию. У меня есть пользовательские страницы A, B 2 и A page, чтобы использовать значение модели. На странице есть кнопка, и если щелкнуть по ней, можно открыть страницу B, когда она намеревается перейти на страницу B, перестроить клиент страницы и вернуться на страницу A, это также привело к перестроению потребителя страницы. Что с ней не так? кто-нибудь может мне помочь? Спасибо. У меня есть поиск много статей, но никто об этом. вот мой код.

модель

class PageModel with ChangeNotifier {

  int _count = 0;

  void addCount() {
    _count += 5;
    notifyListeners();
  }

  int get count => _count;

}

главная

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Provider.debugCheckInvalidValueType = null;

      return MyHomePage();
  }
}

class MyHomePage extends StatefulWidget {

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

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {

    return ChangeNotifierProvider(
      create: (_)=> PageModel(),
      child: MaterialApp(
      home: ProviderPage(),
      ),
    );
  }
}

страница

class ProviderPage extends StatefulWidget {

  @override
  Widget build(BuildContext context) {
    print('ProviderPage create');
  }

  @override
  State<StatefulWidget> createState() {
    return ProviderPageState();
  }

}
class ProviderPageState extends State<ProviderPage> with AutomaticKeepAliveClientMixin {

  @override
  void initState() {
    super.initState();
    print('initState');
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      body: Container(
        margin: EdgeInsets.only(top: 100),
        child: Column(
          children: <Widget>[
            Consumer<PageModel>(builder: (context, data, _) {
              print('ProviderPage Text ${data.count}');
              return Text('${data.count}');
            }),
//              Text('${Provider.of<PageModel>(context).count}'),
            Builder(builder: (_) {
              print('builder RaisedButton');
              return RaisedButton(onPressed: () {
                Provider.of<PageModel>(context, listen: false).addCount();
              }, child: Text('+5'),);
            }),
            RaisedButton(onPressed: () {
              Navigator.of(context).push(
                MaterialPageRoute(
                    builder: (context) {
                      return ProviderPage1();
                    }
                ),);
            }, child: Text('intent'),)
          ],
        ),
      ),
    );
  }

  @override
  void didChangeDependencies() {
    print('didChangeDependencies');
    super.didChangeDependencies();
  }

  @override
  void didUpdateWidget(ProviderPage oldWidget) {
    print('didUpdateWidget');
    super.didUpdateWidget(oldWidget);
  }

  @override
  bool get wantKeepAlive => true;

}

B страница

class ProviderPage1 extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    print('B create');
    return Scaffold(
      body: Container(
        margin: EdgeInsets.only(top: 100),
        child: Center(
          child: Column(
            children: <Widget>[
//              Consumer<PageModel>(builder: (context,data,_) {
//                print('ProviderPage1 Text');
//                return Text('${data.count}');
//              }),
//              Text('${Provider.of<PageModel>(context).count}'),
//              Builder(builder: (_){
//                print('builder RaisedButton1');
//                return RaisedButton(onPressed: (){
//                  Provider.of<PageModel>(context,listen: false).addCount();
//                },child: Text('+5'),);
//              }),
            ],
          ),
        ),
      ),
    );
  }

}

1 Ответ

0 голосов
/ 24 марта 2020

Вы можете ссылаться на
Страницы в стеке Navigator, перестраиваемые при нажатии новой страницы https://github.com/flutter/flutter/issues/11655

Ответ команды флаттера
https://github.com/flutter/flutter/issues/11655#issuecomment -348287396
Работает, как задумано. В общем, вы должны предполагать, что все виджеты могут быть перестроены в любое время, а что нет, это в основном просто оптимизация.

В частности, маршруты будут перестраиваться, потому что их состояние навигатора изменилось, поэтому им может потребоваться обновить как они рисуют кнопки назад и т. п.

https://github.com/flutter/flutter/issues/11655#issuecomment -412413030
Как правило, следует предполагать, что каждый виджет будет перестраивать каждый кадр, и разрабатывать методы сборки так, чтобы они были идемпотентными. (т.е. запуск их несколько раз не должен делать ничего, кроме запуска их один раз), и быстрый (чтобы не было проблем с их многократным запуском). На практике мы используем методы сборки реже этого, но вы не должны на это полагаться.

...