事件总线模式

举报
坚果派 发表于 2022/03/31 21:59:09 2022/03/31
【摘要】 1.轮播图插件()插件名称:推荐指数:基础讲解:使用Demo2.event_bus插件名称:推荐指数:基础讲解:事件总线模式事件总线遵循发布/订阅模式。它允许侦听器订阅事件,并允许发布者触发事件。这使对象可以进行交互,而无需显式定义侦听器并对其进行跟踪。事件总线和MVC 事件总线模式对于解耦MVC (或MVP)应用程序特别有用。一组MVC没问题。但是,一旦有多个MVC组,则这些组将不得不互相...


1.轮播图插件()

插件名称:

推荐指数:

基础讲解:

使用Demo

2.event_bus

插件名称:

推荐指数:

基础讲解:

事件总线模式

事件总线遵循发布/订阅模式。它允许侦听器订阅事件,并允许发布者触发事件。这使对象可以进行交互,而无需显式定义侦听器并对其进行跟踪。

事件总线和MVC

事件总线模式对于解耦MVC (或MVP)应用程序特别有用。

一组MVC没问题。

image-20210209134323982

但是,一旦有多个MVC组,则这些组将不得不互相交谈。这在控制器之间产生了紧密的耦合。

image-20210209134343142

通过事件总线进行通信,减少了耦合。

image-20210209134401743

用法

1.创建事件总线

创建一个实例,EventBus并将其提供给其他类。

通常,每个应用程序只有一个事件总线,但是可以设置多个事件总线来对一组特定的事件进行分组。

import 'package:event_bus/event_bus.dart';
​
EventBus eventBus = EventBus();

注意: 默认构造函数将创建一个异步事件总线。要创建同步总线,必须提供可选sync: true属性。

2.定义事件

任何Dart类都可以用作事件。

class UserLoggedInEvent {
  User user;
​
  UserLoggedInEvent(this.user);
}
​
class NewOrderEvent {
  Order order;
​
  NewOrderEvent(this.order);
}

3.注册监听器

注册特定事件的侦听器:

eventBus.on<UserLoggedInEvent>().listen((event) {
  // All events are of type UserLoggedInEvent (or subtypes of it).
  print(event.user);
});

注册所有事件的侦听器:

eventBus.on().listen((event) {
  // Print the runtime type. Such a set up could be used for logging.
  print(event.runtimeType);
});

使用Demo

3.provider

插件名称:

推荐指数:

基础讲解:

使用Demo

4.url_launcher

插件名称:url_launcher

推荐指数:

基础讲解:

使用Demo

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
​
class Url_launcherPage extends StatefulWidget {
  @override
  _Url_launcherPageState createState() => _Url_launcherPageState();
}
​
class _Url_launcherPageState extends State<Url_launcherPage> {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: ListView(
        children: [
          textButtonItem('打开外部浏览器', "https://cflutter.com"),
          textButtonItem('拨打电话', "tel:10086"),
          textButtonItem('发送短信', "sms:10086"),
          textButtonItem('打开微信', "weixin://"),
          textButtonItem('打开支付宝', 'alipays://'),
          textButtonItem('打开淘宝', 'taobao://'),
          textButtonItem(
              '发送邮件', "mailto:luckly@gmail.com?subject=Test&body=测试"),
          // 协议格式:mailto:<email address>?subject=<subject>&body=<body>
        ],
      ),
    );
  }
​
  Widget textButtonItem(String title, String urlLink) {
    return TextButton(
      child: Text(title),
      onPressed: () async {
        // 苹果App升级用的此方式
        // 前提是首先获取App在苹果里面的地址
        var url = urlLink;
        if (await canLaunch(url)) {
          await launch(url);
        } else {
          throw 'Could not launch $url';
        }
      },
    );
  }
}
​

打开其它应用时,都是改变相应的url协议地址即可,跳转原理参照原生开发使用的url scheme,常用的如下:

QQ: mqq:// 
微信: weixin:// 
京东: openapp.jdmoble:// 测试了,好像不行
淘宝: taobao:// 
美团: imeituan:// 
点评: dianping:// 
1号店: wccbyihaodian:// 
支付宝: alipay:// 
微博: sinaweibo:// 
腾讯微博: TencentWeibo:// 
weico微博: weico:// 
知乎: zhihu:// 
豆瓣fm: doubanradio:// 
网易公开课: ntesopen:// 
Chrome: googlechrome:// 
QQ浏览器: mqqbrowser:// 
uc浏览器: ucbrowser:// 
搜狗浏览器: SogouMSE:// 
百度地图: baidumap:// bdmap:// 
优酷: youku:// 
人人: renren:// 
我查查: wcc:// 
有道词典: yddictproapp:// 
微盘: sinavdisk:// 
名片全能王: camcard://


5.image_gallery_saver

插件名称:保存图片到本地

推荐指数:

基础讲解:关于碰到的问题。可以查看issue

经典错误:在安卓手机上保存不了图片和视频为什么呢?

解决:

你搜遍了网络,很多人会让你加上:android:requestLegacyExternalStorage =“ true”,杀死Android10但 实际上并不起效果。

还必须如作者的demo一样:♡(必须!!)Permission_handler插件,并添加代码:

_requestPermission() async {
 Map<Permission, PermissionStatus> statuses = await [
    Permission.storage,
 ].request();
​
 final info = statuses[Permission.storage].toString();
 print(info);
}

不要再浪费时间了。我浪费了个把小时搜索,作者也不说清楚!

对了,下面的添加没有效果(不要再浪费时间了):

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

是的,我最终也是用了permission_handler插件。调用权限完成

使用Demo

import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

class SaveImageGallyPage extends StatefulWidget {
  @override
  _SaveImageGallyPageState createState() => _SaveImageGallyPageState();
}

class _SaveImageGallyPageState extends State<SaveImageGallyPage> {
  GlobalKey _globalKey = GlobalKey();

  @override
  void initState() {
    super.initState();

    _requestPermission();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Save image to gallery"),
        ),
        body: Center(
          child: Column(
            children: <Widget>[
              RepaintBoundary(
                key: _globalKey,
                child: Container(
                  width: 200,
                  height: 200,
                  color: Colors.red,
                ),
              ),
              Container(
                padding: EdgeInsets.only(top: 15),
                child: RaisedButton(
                  onPressed: _saveScreen,
                  child: Text("Save Local Image"),
                ),
                width: 200,
                height: 44,
              ),
              Container(
                padding: EdgeInsets.only(top: 15),
                child: RaisedButton(
                  onPressed: _getHttp,
                  child: Text("Save network image"),
                ),
                width: 200,
                height: 44,
              ),
              Container(
                padding: EdgeInsets.only(top: 15),
                child: RaisedButton(
                  onPressed: _saveVideo,
                  child: Text("Save network video"),
                ),
                width: 200,
                height: 44,
              ),
              Container(
                padding: EdgeInsets.only(top: 15),
                child: RaisedButton(
                  onPressed: _saveGif,
                  child: Text("Save Gif to gallery"),
                ),
                width: 200,
                height: 44,
              ),
            ],
          ),
        ));
  }

  _requestPermission() async {
    Map<Permission, PermissionStatus> statuses = await [
      Permission.storage,
    ].request();

    final info = statuses[Permission.storage].toString();
    print(info);
    _toastInfo(info);
  }

  _saveScreen() async {
    RenderRepaintBoundary boundary =
        _globalKey.currentContext.findRenderObject();
    ui.Image image = await boundary.toImage();
    ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    final result =
        await ImageGallerySaver.saveImage(byteData.buffer.asUint8List());
    print(result);
    _toastInfo(result.toString());
  }

  _getHttp() async {
    var response = await Dio().get(
        "https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=a62e824376d98d1069d40a31113eb807/838ba61ea8d3fd1fc9c7b6853a4e251f94ca5f46.jpg",
        options: Options(responseType: ResponseType.bytes));
    final result = await ImageGallerySaver.saveImage(
        Uint8List.fromList(response.data),
        quality: 60,
        name: "hello");
    print(result);
    _toastInfo("$result");
  }

  _saveGif() async {
    var appDocDir = await getTemporaryDirectory();
    String savePath = appDocDir.path + "/temp.gif";
    String fileUrl =
        "https://hyjdoc.oss-cn-beijing.aliyuncs.com/hyj-doc-flutter-demo-run.gif";
    await Dio().download(fileUrl, savePath);
    final result = await ImageGallerySaver.saveFile(savePath);
    print(result);
    _toastInfo("$result");
  }

  _saveVideo() async {
    var appDocDir = await getTemporaryDirectory();
    String savePath = appDocDir.path + "/temp.mp4";
    String fileUrl =
        "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4";
    await Dio().download(fileUrl, savePath, onReceiveProgress: (count, total) {
      print((count / total * 100).toStringAsFixed(0) + "%");
    });
    final result = await ImageGallerySaver.saveFile(savePath);
    print(result);
    _toastInfo("$result");
  }

  _toastInfo(String info) {
    Fluttertoast.showToast(msg: info, toastLength: Toast.LENGTH_LONG);
  }
}


6.event_bus

插件名称:

推荐指数:

基础讲解:

使用Demo

7.event_bus

插件名称:

推荐指数:

基础讲解:

使用Demo

8.event_bus

插件名称:

推荐指数:

基础讲解:

使用Demo

9.event_bus

插件名称:

推荐指数:

基础讲解:

使用Demo

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。