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<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页面之间的通信问题,如果还有其它的方法再做总结归纳。谢谢各位看官

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356

推荐阅读更多精彩内容