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小時內刪除侵權內容。