2020-03-20flutter 交互通信

把这几天了解学习的知识汇总了一下,掌握flutter以下几种方式即可应对各种场景了。


一、监听回调

场景,A页面实现回调方法并绑定自定义抽象类,在B页面触发回调A页面的回调方法。

import 'package:flutter/material.dart';

import 'package:scoped_model/scoped_model.dart';

void main() {

  runApp(new RootLayout());

}

class RootLayout extends StatefulWidget {

  @override

  State createState() {

    return new RootLayoutM();

  }

}

class RootLayoutM extends State implements OnDialogClickListener {

  String str = "show simple dialog";

  String showMsg = "show simple dialog";

  @override

  void onOk() {

    print('onOK');

    setState(() {

      showMsg = str + " onOK Click";

    });

  }

  @override

  void onCancel() {

    print('onCancel');

    setState(() {

      showMsg = str + " onCancel Click";

    });

  }

  @override

  Widget build(BuildContext context) {

    return new MaterialApp(

        home: new Scaffold(

      body: new Center(

        child:

            new Text(showMsg, style: new TextStyle(color: Color(0xFF00FF00))),

      ),

      floatingActionButton: new MyFloat(this),

    ));

  }

}

//定义一个抽象类

abstract class OnDialogClickListener {

  void onOk();

  void onCancel();

}

class MyFloat extends StatelessWidget {

  final OnDialogClickListener callback;

  MyFloat(this.callback);

  _showMyMaterialDialog(BuildContext context) {

    print("_showMyMaterialDialog");

    showDialog(

        context: context,

        builder: (context) {

          return new AlertDialog(

            title: new Text("title"),

            content: new Text("内容内容内容内容内容内容内容内容内容内容内容"),

            actions: [

              new FlatButton(

                onPressed: () {

                  callback.onOk();

                  Navigator.of(context).pop();

                },

                child: new Text("确认"),

              ),

              new FlatButton(

                onPressed: () {

                  callback.onCancel();

                  Navigator.of(context).pop();

                },

                child: new Text("取消"),

              ),

            ],

          );

        });

  }

  @override

  Widget build(BuildContext context) {

    // TODO: implement build

    return new FloatingActionButton(

        child: new Text("showDialog"),

        onPressed: () {

          _showMyMaterialDialog(context);

        });

  }

}


二、父页面调用子页面

这里使用全局key>GlobalKey来调用子页的方法或者公共属性.全局key比较耗能。谨慎使用。GlobalKey每个globalkey都是一个在整个应用内唯一的key。globalkey相对而言是比较昂贵的,如果你并不需要globalkey的某些特性,那么可以考虑使用Key、ValueKey、ObjectKey或UniqueKey。

注意:该场景是全局key,意思可以在任意地方使用。

用法:1.在即将被调用的页面声明接收构造方法,接收参数Globalkey。

            2.在使用的页面,new一个有即将被调用页面状态的Globalkey,在生成被调用页面时传入这个globalkey,即可在使用页面随意调用被调用页的公共属性、方法!

其它key扩展,参考

ValueKey:以一个值为key。

        ObjectKey:以一个对象为key。

        UniqueKey:生成唯一的随机数作为key。

        PageStorageKey:专用于存储页面滚动位置的key。


父页面.

class ParentScreen extends StatefulWidget {

    @override

    _ParentScreenState createState() => _ParentScreenState();

}

class _ParentScreenState extends State {

GlobalKey<_ChildScreenState> childKey = GlobalKey();

    @override

    Widget build(BuildContext context) {

        return Column(

            children: [

                ChildScreen(

                    key: childKey

                ),

                RaisedButton(

                    onPressed: (){

                        childKey.currentState.childFunction();

                    },

                    child: Text('点击我调用子组件方法'),

                )

            ],

        );

    }

}

子页面.

class ChildScreen extends StatefulWidget {

    ChildScreen({

        Key key,

    }) : super(key: key);

    @override

    _ChildScreenState createState() => _ChildScreenState();

}

class _ChildScreenState extends State {

    @override

    Widget build(BuildContext context) {

        return Container(


        );

    }

    childFunction(){

        print('this is a childFunction');

    }

}


三、数据监听

ValueListenableBuilder,监听数据变化(单个数值或者对象),比较适合组件的局部刷新。

使用场景,A页面点击item后刷新复选框,复选按钮等。还有收藏一件商品刷新购物车的右上角的件数。

也有人弄成多个地方的刷新,但个人觉得不适合,如果多地方还是考虑使用setstate,不能本末倒置,还是应该恰到好处。

class MyHomePage extends StatefulWidget {

  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override

  _MyHomePageState createState() => _MyHomePageState();

}

class _MyHomePageState extends State {

  final ValueNotifier _counter = ValueNotifier(0);

  final Widget goodJob = const Text('Good job!');

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: Text(widget.title)

      ),

      body: Center(

        child: Column(

          mainAxisAlignment: MainAxisAlignment.center,

          children: [

            Text('You have pushed the button this many times:'),

            ValueListenableBuilder(

              builder: (BuildContext context, int value, Widget child) {

                // This builder will only get called when the _counter

                // is updated.

                return Row(

                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,

                  children: [

                    Text('$value'),

                    child,

                  ],

                );

              },

              valueListenable: _counter,

              // The child parameter is most helpful if the child is

              // expensive to build and does not depend on the value from

              // the notifier.

              child: goodJob,

            )

          ],

        ),

      ),

      floatingActionButton: FloatingActionButton(

        child: Icon(Icons.plus_one),

        onPressed: () => _counter.value += 1,

      ),

    );

  }

}

四、正常传参


场景,A页面传值给B页面,B页面返回数值。例如,选择日期,返回选中值

这类比较普通就放最后了

如果单纯A传B,只需要在A页面构造函数中声明参数,q

且:

Navigator.push(context, new MaterialPageRoute (

        return A(name:xxx);

));

如果需要B返回值,既可以

await Navigator.pushNamed(context,'/router/文件名').then((value){print(value);// --> abc});



目前大致就是A\B页面之间的通信问题,如果还有其它的方法再做总结归纳。谢谢各位看官

你可能感兴趣的:(2020-03-20flutter 交互通信)