• Flutter入门-数据传递


    android开发中,实现数据传递的方式有以下几种:1、intent携带参数;2、构造方法;3、Sharepreference本地保存;4、数据库保存;5、全局单例保存;6、EventBus;7、广播

    在Flutter开发中,同样提供了相对应的方式:
    1、Navigator页面切换的arguments属性
    2、构造方法属性传值
    3、Sharepreference本地保存
    4、数据库保存
    5、全局单例保存
    6、EventBus
    同时Flutter还提供了InheritedWidgetNotification

    一、Navigator的arguments属性

    1、动态路由传参

    push(BuildContext context, Route route)
    
    • 1

    对于android设备,通常使用MaterialPageRoute

     MaterialPageRoute({
        required this.builder,
        super.settings,
        this.maintainState = true,
        super.fullscreenDialog,
      }) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参数builder

    typedef WidgetBuilder = Widget Function(BuildContext context);
    
    • 1

    builder是一个参数为BuildContext类型返回值为widget匿名函数

    参数settings

    
    class RouteSettings {
      /// Creates data used to construct routes.
      const RouteSettings({
        this.name,
        this.arguments,
      });
    
      /// Creates a copy of this route settings object with the given fields
      /// replaced with the new values.
      RouteSettings copyWith({
        String? name,
        Object? arguments,
      }) {
        return RouteSettings(
          name: name ?? this.name,
          arguments: arguments ?? this.arguments,
        );
      }
    
      /// The name of the route (e.g., "/settings").
      ///
      /// If null, the route is anonymous.
      final String? name;
    
      /// The arguments passed to this route.
      ///
      /// May be used when building the route, e.g. in [Navigator.onGenerateRoute].
      final Object? arguments;
    
      
      String toString() => '${objectRuntimeType(this, 'RouteSettings')}("$name", $arguments)';
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    参数settings是RouteSettings类,该类包含两个属性,name属性,为该路由的名字;属性arguments的类型是object,说明可以是任意类型的数据。

    自定义的参数类

    class Arguments {
      String _name = "";
      int _age = 0;
    
      String get name => _name;
    
      set name(String value) {
        _name = value;
      }
    
      int get age => _age;
    
      set age(int value) {
        _age = value;
      }
    
      
      String toString() {
        return 'Arguments{_name: $_name, _age: $_age}';
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
                    Arguments arguments = Arguments();
                    arguments.name = "我是从上个页面传的";
                    arguments.age = 18;
    
                    Navigator.push(context,MaterialPageRoute(
                                builder: (context) => SecondPage(),
                                settings: RouteSettings(name: 'second', arguments: arguments)))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    命名路由传参

    函数原型

    pushNamed<T extends Object?>(
        BuildContext context,
        String routeName, {
        Object? arguments,
      })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    context:上下文环境
    routeName:路由名称
    arguments:参数(可选)

     Arguments arguments = Arguments();
     arguments.name = "我是从上个页面传的";
     arguments.age = 18;
     Navigator.pushNamed(context, "second", arguments: arguments);
    
    • 1
    • 2
    • 3
    • 4

    二、构造方法传参

    import 'package:flutter/material.dart';
    import 'package:flutter_hello/arguments.dart';
    
    class ConstructHomePage extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: HomePage(),
        );
      }
    }
    
    class HomePage extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: GestureDetector(
              child: Text('跳转下一页'),
              onTap: () {
                Arguments arguments = Arguments();
                arguments.name = "我是来源于首页";
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (BuildContext context) =>
                            ConstructSecondPage(arguments)));
              },
            ),
          ),
        );
      }
    }
    
    class ConstructSecondPage extends StatelessWidget {
      Arguments arguments;
    
      ConstructSecondPage(this.arguments);
    
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Center(
              child: Text('${arguments.name}'),
            ),
          ),
        );
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    Navigator使用抛出的异常:

    Navigator operation requested with a context that does not include a Navigator.
    
    • 1

    解决方案:
    如上面demo,MaterialApp的home指向的widget使用StatelessWidget或者StatefulWidget包一层即可

    三、SharedPreferences

    添加相关依赖

    dependencies:
      shared_preferences: ^2.0.15
    
    • 1
    • 2

    使用

    import 'package:flutter/material.dart';
    import 'package:shared_preferences/shared_preferences.dart';
    
    class MySharedPreference extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: SharedPreferenceHome(),
        );
      }
    }
    
    class SharedPreferenceHome extends StatelessWidget {
      void setString(String key, String value) async {
        var sp = await SharedPreferences.getInstance();
        sp.setString(key, value);
      }
    
      
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: GestureDetector(
              child: Text('下一个页面'),
              onTap: () {
                setString('arguments', '我是SharedPreferences传值');
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) => SharedPreferenceSecond()));
              },
            ),
          ),
        );
      }
    }
    
    class SharedPreferenceSecond extends StatefulWidget {
      
      State<SharedPreferenceSecond> createState() => _SharedPreferenceSecondState();
    }
    
    class _SharedPreferenceSecondState extends State<SharedPreferenceSecond> {
      String arguments = "";
    
      void getString(String key, [String defaultValue = '']) async {
        SharedPreferences sp = await SharedPreferences.getInstance();
        arguments=sp.getString(key) ?? defaultValue;
        setState(() {
          
        });
      }
    
      
      void initState() {
        super.initState();
        getString('arguments');
      }
    
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Center(
              child: Text('${arguments}'),
            ),
          ),
        );
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    SharedPreferences的所有操作都是异步的,所以需要进一步包装。

    四、数据库(sqflite)

    1、添加依赖

    dependencies:
      sqflite: ^2.2.0+3
    
    • 1
    • 2

    2、自定义DataBase帮助类

    
    class SQLHelper {
    
      static Future<Database> getDb() async {
        // Get a location using getDatabasesPath
        var databasesPath = await getDatabasesPath();
        String path = join(databasesPath, 'hello.db');
    
        // open the database
        Database database = await openDatabase(path, version: 1,
            onCreate: (Database db, int version) async {
          // When creating the db, create the table
          await db.execute(
              'CREATE TABLE IF NOT EXISTS People (id INTEGER PRIMARY KEY, name TEXT, age INTEGER, num INTEGER)');
        });
        return database;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3、自定义类

    ///自定义people类
    class People {
      String _name="";
      int _age=0;
      int _num=0;
    
      People();
    
      String get name => _name;
    
      set name(String value) {
        _name = value;
      }
    
      int get age => _age;
    
      set age(int value) {
        _age = value;
      }
    
      int get num => _num;
    
      set num(int value) {
        _num = value;
      }
    
      People.fromJson(Map<String, dynamic> peopleJson) {
        _name = peopleJson['name'];
        _age = peopleJson['age'];
        _num = peopleJson['num'];
      }
    
      Map<String, dynamic> toJson() {
        return {"name": _name, "age": _age, "num": _num};
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    4、实现插入类到数据库

    void insertPeople(People people) async {
        final Database db = await SQLHelper.getDb();
        db.insert('People', people.toJson());
      }
    
    • 1
    • 2
    • 3
    • 4

    5、实现查询数据库

    Future<People?> getPeople() async {
        final Database db = await SQLHelper.getDb();
        List<Map<String, dynamic>> list =
            await db.query('People', columns: ['name', 'age', 'num']);
        if (list != null && list.length > 0) {
          return People.fromJson(list.first);
        }
        return null;
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    完整的dart文件

    import 'package:flutter/material.dart';
    import 'package:sqflite/sqflite.dart';
    import 'package:path/path.dart';
    
    class SQLHelper {
    
      static Future<Database> getDb() async {
        // Get a location using getDatabasesPath
        var databasesPath = await getDatabasesPath();
        String path = join(databasesPath, 'hello.db');
    
        // open the database
        Database database = await openDatabase(path, version: 1,
            onCreate: (Database db, int version) async {
          // When creating the db, create the table
          await db.execute(
              'CREATE TABLE IF NOT EXISTS People (id INTEGER PRIMARY KEY, name TEXT, age INTEGER, num INTEGER)');
        });
        return database;
      }
    }
    
    ///自定义people类
    class People {
      String _name="";
      int _age=0;
      int _num=0;
    
      People();
    
      String get name => _name;
    
      set name(String value) {
        _name = value;
      }
    
      int get age => _age;
    
      set age(int value) {
        _age = value;
      }
    
      int get num => _num;
    
      set num(int value) {
        _num = value;
      }
    
      People.fromJson(Map<String, dynamic> peopleJson) {
        _name = peopleJson['name'];
        _age = peopleJson['age'];
        _num = peopleJson['num'];
      }
    
      Map<String, dynamic> toJson() {
        return {"name": _name, "age": _age, "num": _num};
      }
    }
    
    ///首页
    class MySqfliteHome extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: MySqfliteHomePage(),
        );
      }
    }
    
    class MySqfliteHomePage extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: GestureDetector(
              child: Text('下一页'),
              onTap: () {
                People people = new People();
                people.name = 'Hello';
                people.age = 18;
                people.num = 2022;
                insertPeople(people);
                Navigator.push(context,
                    MaterialPageRoute(builder: (context) => MySqfliteSecondPage()));
              },
            ),
          ),
        );
      }
    
      void insertPeople(People people) async {
        final Database db = await SQLHelper.getDb();
        db.insert('People', people.toJson());
      }
    }
    
    ///第二页页面
    class MySqfliteSecondPage extends StatefulWidget {
      
      State<MySqfliteSecondPage> createState() => _MySqfliteSecondPageState();
    }
    
    class _MySqfliteSecondPageState extends State<MySqfliteSecondPage> {
      People people = People();
    
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Center(
              child: Column(
                children: [
                  Text('姓名:${people.name}'),
                  Text('年龄:${people.age}'),
                  Text('编号:${people.num}')
                ],
              ),
            ),
          ),
        );
      }
    
      
      void initState() {
        super.initState();
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          // getPeople().then((value) {
          //   people = value!;
          //   setState(() {});
          // });
          initData();
        });
      }
    
      void initData() async {
        people = (await getPeople())!;
        setState(() {});
      }
    
      Future<People?> getPeople() async {
        final Database db = await SQLHelper.getDb();
        List<Map<String, dynamic>> list =
            await db.query('People', columns: ['name', 'age', 'num']);
        if (list != null && list.length > 0) {
          return People.fromJson(list.first);
        }
        return null;
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150

    五、全局单例实现(多用于不需要保存到本地的全局属性)

    1、单例的定义

    class GlobalSingleInstance {
      ///单例写法1
      // GlobalSingleInstance._internal();
      //
      // factory GlobalSingleInstance() => _instance;
      //
      // static late final GlobalSingleInstance _instance = GlobalSingleInstance._internal();
    
      ///单例写法2
      factory GlobalSingleInstance() => _getShared();
    
      static GlobalSingleInstance get _instance => _getShared();
      static GlobalSingleInstance? instance;
    
      GlobalSingleInstance._internal() {
        // 初始化
      }
    
      static GlobalSingleInstance _getShared() {
        instance ??= GlobalSingleInstance._internal();
        return instance!;
      }
    
      int _gloableNum = 0;
      int get gloableNum => _gloableNum;
    
      set gloableNum(int value) {
        _gloableNum = value;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    2、单例多页面调用

    import 'package:flutter/material.dart';
    
    class GlobalSingleInstance {
      ///单例写法1
      // GlobalSingleInstance._internal();
      //
      // factory GlobalSingleInstance() => _instance;
      //
      // static late final GlobalSingleInstance _instance = GlobalSingleInstance._internal();
    
      ///单例写法2
      factory GlobalSingleInstance() => _getShared();
    
      static GlobalSingleInstance get _instance => _getShared();
      static GlobalSingleInstance? instance;
    
      GlobalSingleInstance._internal() {
        // 初始化
      }
    
      static GlobalSingleInstance _getShared() {
        instance ??= GlobalSingleInstance._internal();
        return instance!;
      }
    
      int _gloableNum = 0;
      int get gloableNum => _gloableNum;
    
      set gloableNum(int value) {
        _gloableNum = value;
      }
    }
    
    class GloableSingleInstance extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: GloableSingleInstanceHome(),
        );
      }
    }
    
    class GloableSingleInstanceHome extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: GestureDetector(
              child: Text('下一页'),
              onTap: () {
                GlobalSingleInstance._instance.gloableNum = 20;
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) => GloableSingleInstanceSecond()));
              },
            ),
          ),
        );
      }
    }
    
    class GloableSingleInstanceSecond extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Text('当前数据:${GlobalSingleInstance._instance.gloableNum}'),
          ),
        );
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    六、EventBus实现

    EventBus是基于事件总线,采用订阅-观察者模式,可以订阅指定的‘事件’,也可以订阅所有‘事件’

    1、添加依赖

    dependencies:
         event_bus: ^2.0.0
    
    • 1
    • 2

    2、定义监听的对象

    class CustomEvent {
      String msg;
    
      CustomEvent(this.msg);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3、订阅监听

    
      void initState() {
        super.initState();
        subscription = eventBus.on<CustomEvent>().listen((event) {
          setState(() {
            _msg = event.msg;
          });
        });
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4、取消订阅监听

    
      void dispose() {
        subscription.cancel();
        super.dispose();
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5、发布消息

    eventBus.fire(CustomEvent('总线发射${Random().nextInt(100)}'));
    
    • 1

    完整代码

    import 'dart:async';
    import 'dart:math';
    
    import 'package:event_bus/event_bus.dart';
    import 'package:flutter/material.dart';
    
    EventBus eventBus = EventBus();
    
    class ShareDataWithEventBus extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: MyFirstPage(),
        );
      }
    }
    
    class CustomEvent {
      String msg;
    
      CustomEvent(this.msg);
    }
    
    class MyFirstPage extends StatefulWidget {
      
      State<MyFirstPage> createState() => _MyFirstPageState();
    }
    
    class _MyFirstPageState extends State<MyFirstPage> {
      late StreamSubscription<CustomEvent> subscription;
      String _msg="";
    
      
      void initState() {
        super.initState();
        subscription = eventBus.on<CustomEvent>().listen((event) {
          setState(() {
            _msg = event.msg;
          });
        });
      }
    
      
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Text(
              '$_msg',
              style: TextStyle(color: Colors.blue, fontSize: 20),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (BuildContext context) => MySecondPage()));
            },
          ),
        );
      }
    
      
      void dispose() {
        subscription.cancel();
        super.dispose();
      }
    }
    
    class MySecondPage extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('使用Event bus'),
              centerTitle: true,
              leading: BackButton(
                onPressed: () {
                  Navigator.pop(context);
                  eventBus.fire(CustomEvent('总线发射${Random().nextInt(100)}'));
                },
              ),
            ),
            body: Text('我是第二个页面'),
          ),
        );
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    七、基于InheritedWidget

    InheritedWidget可以实现数据从父控件传递到子控件。

    1、继承InheritedWidget

    class CountContainer extends InheritedWidget {
      final int count;
    
      CountContainer({
        required this.count,
        required Widget child}): super(child: child);
    
      
      bool updateShouldNotify(CountContainer oldWidget) => count != oldWidget.count;
    
      static CountContainer? of(BuildContext context) =>context.dependOnInheritedWidgetOfExactType();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2、应用

    class WidgetParentToChild extends StatefulWidget {
      
      State<WidgetParentToChild> createState() => _WidgetParentToChildState();
    }
    
    class _WidgetParentToChildState extends State<WidgetParentToChild> {
      int _count=0;
    
      void _incrementCounter(){
        _count=Random().nextInt(100);
        setState(() {});
      }
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            floatingActionButton: FloatingActionButton(
              onPressed: (){
                _incrementCounter();
              },
            ),
            body: Center(
              child: CountContainer(
                count: _count,
                child: CountContainerChild(),
              ),
            ),
          ),
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    完整代码

    import 'dart:math';
    
    import 'package:flutter/material.dart';
    
    class WidgetParentToChild extends StatefulWidget {
      
      State<WidgetParentToChild> createState() => _WidgetParentToChildState();
    }
    
    class _WidgetParentToChildState extends State<WidgetParentToChild> {
      int _count=0;
    
      void _incrementCounter(){
        _count=Random().nextInt(100);
        setState(() {});
      }
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            floatingActionButton: FloatingActionButton(
              onPressed: (){
                _incrementCounter();
              },
            ),
            body: Center(
              child: CountContainer(
                count: _count,
                child: CountContainerChild(),
              ),
            ),
          ),
        );
      }
    }
    
    class CountContainer extends InheritedWidget {
      final int count;
    
      CountContainer({
        required this.count,
        required Widget child}): super(child: child);
    
      
      bool updateShouldNotify(CountContainer oldWidget) => count != oldWidget.count;
    
      static CountContainer? of(BuildContext context) =>context.dependOnInheritedWidgetOfExactType();
    }
    class CountContainerChild extends StatelessWidget{
      
      Widget build(BuildContext context) {
           final int number=CountContainer.of(context)!.count;
           return Text("$number", style: TextStyle(color: Colors.amber, fontSize: 40));
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    八、基于Notification

    Notification可以实现数据由子控件传递到父控件

    1、继承Notification

    class CustomNotification extends Notification {
      final String msg;
    
      CustomNotification(this.msg);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、NotificationListener监听

    class ShareDataFromChildToParent extends StatefulWidget {
      
      State<ShareDataFromChildToParent> createState() =>
          _ShareDataFromChildToParentState();
    }
    
    class _ShareDataFromChildToParentState extends State<ShareDataFromChildToParent> {
      String _msg = "";
    
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: NotificationListener<CustomNotification>(
              child: Center(
                child: Column(
                  children: [
                    ShareDataChild(),
                    Text(
                      '$_msg',
                      style: TextStyle(color: Colors.black, fontSize: 20),
                    ),
                  ],
                ),
              ),
              onNotification: (notification) {
                setState(() {
                  _msg = notification.msg;
                  print(_msg);
                });
                return false;
              },
            ),
          ),
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    3、使用dispatch发送数据

     onPressed: () => CustomNotification('Hi,I`am from child')
                .dispatch(context)
    
    • 1
    • 2

    4、完整代码

    import 'package:flutter/material.dart';
    
    /**
     * 使用Notification
     */
    class ShareDataFromChildToParent extends StatefulWidget {
      
      State<ShareDataFromChildToParent> createState() =>
          _ShareDataFromChildToParentState();
    }
    
    class _ShareDataFromChildToParentState extends State<ShareDataFromChildToParent> {
      String _msg = "";
    
      
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: NotificationListener<CustomNotification>(
              child: Center(
                child: Column(
                  children: [
                    ShareDataChild(),
                    Text(
                      '$_msg',
                      style: TextStyle(color: Colors.black, fontSize: 20),
                    ),
                  ],
                ),
              ),
              onNotification: (notification) {
                setState(() {
                  _msg = notification.msg;
                  print(_msg);
                });
                return false;
              },
            ),
          ),
        );
      }
    }
    
    class CustomNotification extends Notification {
      final String msg;
    
      CustomNotification(this.msg);
    }
    
    class ShareDataChild extends StatelessWidget{
      
      Widget build(BuildContext context) {
        return Center(
          child: MaterialButton(
            onPressed: () => CustomNotification('Hi,I`am from child')
                .dispatch(context),
            child: Text('发送消息'),
          ),
        );
      }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
  • 相关阅读:
    Gartner:2022年全球IT支出将超4万亿美元,软件增速最高
    spring源码环境搭建,测试springmvc
    双向认证配置
    synchronized的优化机制和一些多线程的常见类
    【Java那些年系列-启航篇 04】Java程序架构:深入理解类与对象的设计原则
    简单工厂模式的实践
    VulnHub JANGOW
    jQuery 语法
    sa-token学习
    【MATLAB】常见语法结构和实用操作
  • 原文地址:https://blog.csdn.net/u011557841/article/details/127647621