事件总线模式
1.轮播图插件()
插件名称:
推荐指数:
基础讲解:
使用Demo
2.event_bus
插件名称:
推荐指数:
基础讲解:
事件总线遵循发布/订阅模式。它允许侦听器订阅事件,并允许发布者触发事件。这使对象可以进行交互,而无需显式定义侦听器并对其进行跟踪。
事件总线和MVC
事件总线模式对于解耦 (或)应用程序特别有用。
一组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<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
推荐指数:
基础讲解:
使用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
插件名称:保存图片到本地
推荐指数:
基础讲解:关于碰到的问题。可以查看
经典错误:在安卓手机上保存不了图片和视频为什么呢?
解决:
你搜遍了网络,很多人会让你加上: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
- 点赞
- 收藏
- 关注作者
评论(0)