事件總線模式

      網友投稿 755 2025-04-04

      1.輪播圖插件()

      插件名稱:

      推薦指數:

      基礎講解:

      使用Demo

      事件總線模式

      2.event_bus

      插件名稱:

      推薦指數:

      基礎講解:

      事件總線模式

      事件總線遵循發布/訂閱模式。它允許偵聽器訂閱事件,并允許發布者觸發事件。這使對象可以進行交互,而無需顯式定義偵聽器并對其進行跟蹤。

      事件總線和MVC

      事件總線模式對于解耦MVC (或MVP)應用程序特別有用。

      一組MVC沒問題。

      但是,一旦有多個MVC組,則這些組將不得不互相交談。這在控制器之間產生了緊密的耦合。

      通過事件總線進行通信,減少了耦合。

      用法

      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().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 { @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:?subject=&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但 實際上并不起效果。

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

      對了,下面的添加沒有效果(不要再浪費時間了):

      是的,我最終也是用了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 { 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: [ 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 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

      MVC

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Excel2013中怎么隔幾行就插入空行(excel每隔十行插一行空行)
      下一篇:WPS調整行間距在哪兒操作?(wps里怎么調行間距)
      相關文章
      亚洲天堂中文字幕| 国产亚洲?V无码?V男人的天堂 | 精品亚洲成A人无码成A在线观看 | 亚洲精品永久在线观看| 亚洲一区免费在线观看| 亚洲国产精品久久久久秋霞影院| 亚洲黑人嫩小videos| 老汉色老汉首页a亚洲| 久久精品a亚洲国产v高清不卡| 亚洲国产精品久久久久| 亚洲人成网站在线播放影院在线| 婷婷精品国产亚洲AV麻豆不片| 国产精品亚洲精品日韩已满| 亚洲精品无码乱码成人| 亚洲人成色77777| 亚洲av一综合av一区| 亚洲视频在线免费观看| 亚洲精品美女久久久久| 亚洲中字慕日产2020| 亚洲第一区二区快射影院| 亚洲精品无码少妇30P| 亚洲A丁香五香天堂网| 亚洲综合精品网站在线观看| 亚洲午夜久久久影院伊人| 亚洲精品中文字幕无码蜜桃| 久久精品国产亚洲AV麻豆王友容| 亚洲电影一区二区三区| 久久亚洲AV无码精品色午夜麻豆| 久久亚洲精品国产精品| 亚洲乱码在线播放| 亚洲人成网站在线在线观看| 国产亚洲日韩在线a不卡| 亚洲七七久久精品中文国产| 亚洲熟妇无码八AV在线播放| 久久久久亚洲精品成人网小说| 久久亚洲熟女cc98cm| 亚洲色偷偷综合亚洲AV伊人蜜桃| 亚洲av成人片在线观看| 亚洲一区日韩高清中文字幕亚洲| 亚洲精品无码乱码成人 | 久久亚洲AV成人无码|