Flutter Provider入门(二)

任何一个App都会有username这种需要全局使用的数据
任何一个App都会有userdata数据发生变化相关UI的同步更新的需求

本节我们来使用Provider解决第二个问题,
请先阅读Flutter Provider入门(一)
首先改造一下MyApp类
将包裹AppWidget的Provider更改为ChangeNotifierProvider

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      builder: (context) => TitleText(),
       child: MaterialApp(
         title: 'flutter demo',
         home: const MyHomePage(),
    ),
    );
  }
}

改造一下title.dart文件

import 'package:flutter/foundation.dart';

class TitleText with ChangeNotifier{
  String  _title = '12345';
  String  get title => _title;
  void set(String title) {
    _title = title;
    notifyListeners();
  }
}

运行程序,得到一下错误提示:

════════ Exception caught by foundation library ════════════════════════════════════════════════════
The following assertion was thrown while dispatching notifications for TitleText:
setState() or markNeedsBuild() called during build.

意思就是我们在更新UI的时候又触发UI更改,问题来自以下代码

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    final titleText = Provider.of(context);
   /// 在build中设置set会导致build的调用,从而引起死循环
    titleText.set('我是共享文字');
    return Scaffold(
        appBar: AppBar(title: Text('first')),
        body: Center(
            child: FlatButton(
            onPressed: (){
                 Navigator.push(context, MaterialPageRoute(builder: (context){
                      return SecondRoute();
               }));
            },
            child: Text(titleText.title)
            )
        ),
        //floatingActionButton : const IncrementCounterButton()
    );
  }
}

删除

titleText.set('我是共享文字');

运行代码,可以看到点击SecondRoute中的更新按钮,
两个页面的按钮文字都同步发生了变化。

让我们来研究一下官方的Demo
并对诸如ChangeNotifierProvider从何处来,用法为何做一个深入
Flutter Provider入门(三)

你可能感兴趣的:(Flutter Provider入门(二))