美文网首页
2020-03-20flutter 交互通信

2020-03-20flutter 交互通信

作者: 没有钱也很认真 | 来源:发表于2020-03-20 18:09 被阅读0次

    把这几天了解学习的知识汇总了一下,掌握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<StatefulWidget> createState() {

        return new RootLayoutM();

      }

    }

    class RootLayoutM extends State<RootLayout> 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: <Widget>[

                  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<ParentScreen> {

    GlobalKey<_ChildScreenState> childKey = GlobalKey();

        @override

        Widget build(BuildContext context) {

            return Column(

                children: <Widget>[

                    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<ChildScreen> {

        @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<MyHomePage> {

      final ValueNotifier<int> _counter = ValueNotifier<int>(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: <Widget>[

                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: <Widget>[

                        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<void> (

            return A(name:xxx);

    ));

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

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

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

    相关文章

      网友评论

          本文标题:2020-03-20flutter 交互通信

          本文链接:https://www.haomeiwen.com/subject/evujyhtx.html