Flutter移动开发常用插件
Flutter常用知识
获取状态栏高度
import "dart:ui";
MediaQueryData.fromWindow(window).padding.top;
/// ToolBar的高度
const double kToolbarHeight = 56.0;
/// 底部导航栏的高度
const double kBottomNavigationBarHeight = 56.0;
/// 包含文本的标签栏的高度
const double kTextTabBarHeight = 48.0;
设置沉浸式状态栏
import 'dart:io';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
if (Platform.isAndroid) {
SystemUiOverlayStyle systemUiOverlayStyle =
SystemUiOverlayStyle(statusBarColor: Colors.transparent);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
}
}
APP设置横屏
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations(
[DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
runApp(MyApp());
}
渐变标题栏
Scaffold(
extendBodyBehindAppBar: true, // 将body至于Appbar下
appBar: AppBar(
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xffc2e59c),
Color(0xff64b3f4),
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
)
),
),
// 设置AppBar形状
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(bottom: Radius.circular(40)),
),
),
)
设置底部虚拟按键颜色
import 'dart:io';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
if (Platform.isAndroid) {
SystemUiOverlayStyle style = SystemUiOverlayStyle(
systemNavigationBarColor: Color(0xFFFFFFFF), // 背景色
systemNavigationBarIconBrightness: Brightness.dark, // 图标色
);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
}
}
在runApp()前初始方法
WidgetsFlutterBinding.ensureInitialized();
更改某一页状态栏导航栏颜色
AnnotatedRegion(
value: SystemUiOverlayStyle.light,
child: Scaffold(body:Text('页面'),),
);
更改某一页状态栏或导航栏显示样式后其他页面改回去
WillPopScope(
onWillPop: () async {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]);
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
systemNavigationBarColor: Colors.white,
systemNavigationBarIconBrightness: Brightness.dark));
return true;
},
child: Scaffold(),
);
监听APP生命周期
import 'package:flutter/material.dart';
///前后台应用测试
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver{
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this); //添加观察者
}
@override
void dispose() {
super.dispose();
print('YM--------dispose');
WidgetsBinding.instance.removeObserver(this); //添加观察者
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: Text('Material App Bar'),
),
body: Center(
child: Container(
child: Text('Hello World'),
),
),
),
);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
switch (state) {
case AppLifecycleState.inactive:
// 应用程序处于闲置状态并且没有收到用户的输入事件。
//注意这个状态,在切换到后台时候会触发,所以流程应该是先冻结窗口,然后停止UI
print('YM----->AppLifecycleState.inactive');
break;
case AppLifecycleState.paused:
// 应用程序处于不可见状态
print('YM----->AppLifecycleState.paused');
break;
case AppLifecycleState.resumed:
// 进入应用时候不会触发该状态
// 应用程序处于可见状态,并且可以响应用户的输入事件。它相当于 Android 中Activity的onResume。
print('YM----->AppLifecycleState.resumed');
break;
case AppLifecycleState.detached:
//当前页面即将退出
print('YM----->AppLifecycleState.detached');
break;
}
}
///当前系统改变了一些访问性活动的回调
@override
void didChangeAccessibilityFeatures() {
super.didChangeAccessibilityFeatures();
print("YM-----@@@@@@@@@ didChangeAccessibilityFeatures");
}
///低内存回调
@override
void didHaveMemoryPressure() {
super.didHaveMemoryPressure();
print("YM-----@@@@@@@@@ didHaveMemoryPressure");
}
///用户本地设置变化时调用,如系统语言改变
@override
void didChangeLocales(List<Locale> locale) {
super.didChangeLocales(locale);
print("YM-----@@@@@@@@@ didChangeLocales");
}
///应用尺寸改变时回调,例如旋转
@override
void didChangeMetrics() {
super.didChangeMetrics();
Size size = WidgetsBinding.instance.window.physicalSize;
print("YM-----@@@@@@@@@ didChangeMetrics :宽:${size.width} 高:${size.height}");
}
@override
Future<bool> didPopRoute() {
print('YM--------didPopRoute');//页面弹出
return Future.value(false);//true为拦截,false不拦截
}
@override
Future<bool> didPushRoute(String route) {
print('YM--------PushRoute');
return Future.value(true);
}
@override
Future<bool> didPushRouteInformation(RouteInformation routeInformation) {
print('YM--------didPushRouteInformation');
return Future.value(true);
}
//文字大小改变时候的监听
@override
void didChangeTextScaleFactor() {
print("YM--------@@@@@@@@@ didChangeTextScaleFactor :${WidgetsBinding.instance.window.textScaleFactor}");
}
@override
void didChangePlatformBrightness() {
final window = WidgetsBinding.instance.window;
final brightness = window.platformBrightness;
// Brightness.light 亮色
// Brightness.dark 暗色
print('YM----平台主题改变----didChangePlatformBrightness$brightness');
// window.onPlatformBrightnessChanged = () {
// // This callback gets invoked every time brightness changes
// final brightness = window.platformBrightness;
// print('YM----平台亮度改变----didChangePlatformBrightness$brightness');
// };
}
}
ElevatedButton设置圆角
ElevatedButton(
onPressed: () {},
child: Text('Button'),
style: ElevatedButton.styleFrom(shape: StadiumBorder()),
)
点击空白处取消TextField焦点收起键盘
GestureDetector(
// 空白处点击生效
behavior: HitTestBehavior.translucent,
onTap: () {
// 触摸收起键盘
FocusScope.of(context).requestFocus(FocusNode());
},
child: ****视图内容***
}
内容不随键盘滚动,防止出现软键盘内容溢出
Scafflod(
// 已删除resizeToAvoidBottomPadding: false
resizeToAvoidBottomInset: false
)
软键盘弹出遮挡住内容
AnimatedPadding(
padding: MediaQuery.of(context).viewInsets,
duration: const Duration(milliseconds: 100),
child: ...
);
滑动删除列表
Dismissible(
key: Key(item),
onDismissed: (direction){
setState(() {
items.removeAt(index);
});
final snackbar = SnackBar(content: Text("${item}已移除"));
Scaffold.of(context).showSnackBar(snackbar);
},
background: Container(
alignment: Alignment.center,
child: Text("左滑删除", style: TextStyle(color: Colors.white)),
color: Colors.red,
),
child: ListTile(title: Text(item))
)
双击退出效果
要想实现双击退出效果,必须把 WillPopScope 控件放在最外围
import 'package:flutter/material.dart';
class TheWillPopScope extends StatelessWidget {
DateTime _lastQUitTime;
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(
body: Center(
child: Text("点击退出按钮,询问是否退出"),
)
),
onWillPop: () async {
if(_lastQUitTime == null || DateTime.now().difference(_lastQUitTime).inSeconds >1){
_lastQUitTime = DateTime.now();
return false;
}else{
// 推出页面
await Navigator.of(context).pop(true);
// 退出程序
// await SystemChannels.platform.invokeMethod('SystemNavigator.pop');
return true;
}
},
);
}
}
去掉顶部默认Padding
MediaQUery.removePadding(
removeTop: true
)
去掉TextField下划线
TextField(
decoration: InputDecoration(
border: InputBorder.none,
),
)
监听滑动通知
NotificationListener(
onNotification: (scrollNotification){
if(scrollNotification is ScrollUpdateNotification){
...
}
},
child:
)
查看图片
可以通过拖动以平移、缩放和拖放子组件
InteractiveViewer(
child: Image.asset('assets/images/go_board_09x09.png'),
)
左滑返回
return new MaterialApp(
home: new HomePage(),
theme: new ThemeData(platform: TargetPlatform.iOS),
);
退出应用
SystemChannels.platform.invokeMethod("SystemNavigator.pop");
子元素被父元素限制宽高
UnconstrainedBox{
constrainedAxis: Axis.vertical,
child: SizedBox(
width: width;
child: Dialog(),
),
}
封装的评星
class StarRating extends StatelessWidget {
final double rating;
final double maxRating;
final Widget unselectedImage;
final Widget selectedImage;
final int count;
final double size;
final Color unselectedColor;
final Color selectedColor;
StarRating({
@required this.rating, // 当前评分
this.maxRating = 10, // 最高评分
Widget unselectedImage,
Widget selectedImage,
this.count = 5, // 星星的个数
this.size = 40,
this.unselectedColor = Colors.grey,
this.selectedColor = Colors.orange
}) : unselectedImage = unselectedImage ?? Icon(Icons.star, color: unselectedColor, size: size),
selectedImage = selectedImage ?? Icon(Icons.star, color: selectedColor, size: size);
@override
Widget build(BuildContext context) {
return Stack(
children: [
UnSelectStar(),
SelectedStar()
],
);
}
// 宽度 = 评分 / 每个星星代表的分数 * 星星的大小
// var width = ping / (total / count) * size;
Widget UnSelectStar() {
return Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(count, (index) =>
unselectedImage
),
);
}
Widget SelectedStar() {
double width = rating / (maxRating / count) * size;
return ClipRect(
clipper: MyClipRect(width: width),
child: Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(5, (index) =>
selectedImage
),
),
);
}
}
class MyClipRect extends CustomClipper<Rect>{
double width;
MyClipRect({this.width});
@override
getClip(Size size) {
return Rect.fromLTRB(0, 0, width, size.height);
}
@override
bool shouldReclip(MyClipRect oldClipper) {
return width != oldClipper;
}
}
SharedPreference封装(非nullsafe)
import 'package:shared_preferences/shared_preferences.dart';
class DataCache {
static DataCache _insatnce = DataCache._();
factory DataCache() => _insatnce;
DataCache._();
static late SharedPreferences pre;
static Future<void> init() async {
if (pre == null) {
pre = await SharedPreferences.getInstance();
}
}
Future<bool> setString(String key, String value) {
return pre.setString(key, value);
}
Future<bool> setDouble(String key, double value) {
return pre.setDouble(key, value);
}
Future<bool> setInt(String key, int value) {
return pre.setInt(key, value);
}
Future<bool> setBool(String key, bool value) {
return pre.setBool(key, value);
}
Future<bool> setStringList(String key, List<String> value) {
return pre.setStringList(key, value);
}
getString(String key) {
var result = pre.get(key);
return result ?? false;
}
getDouble(String key) {
var result = pre.get(key);
return result ?? false;
}
getInt(String key) {
var result = pre.get(key);
return result ?? false;
}
getBool(String key) {
var result = pre.get(key);
return result ?? false;
}
getStringList(String key) {
var result = pre.get(key);
return result ?? false;
}
}
第三方包
assets_audio_player 音频播放
animations 更多动画
auto_route 路由管理
azlistview A-Z的选择列表
badges 消息提示小红点
barcode_widget 生成二维码
bottom_sheet 第三方好用的BottomSheet
cached_network_image 网络缓存图片
camera 调用系统相机
carousel_slider 轮播图
city_pickers 城市选择器
collection 集合的样式包含实用工具函数和类,以使处理集合更加容易。
color_thief_flutter 提取图片颜色
cookie jar dio cookie manager依赖包
crypto 密码加密
custom_nested_scroll_view 解决NestedScrollView无法实现下拉放大
device_info 获取设备信息
device_preview 预览程序
dio http请求库
dio_cookie_manager Cookie管理
extended_image 强大的官方 Image 扩展组件, 支持加载以及失败显示,缓存网络图片,缩放拖拽图片,图片浏览(微信掘金效果),滑动退出页面(微信掘金效果),编辑图片(裁剪旋转翻转),保存,绘制自定义效果等功能
fluro 路由管理
flustars flustars依赖于Dart常用工具类库common_utils,以及对其他第三方库封装,致力于为大家分享简单易用工具类。如果你有好的工具类欢迎PR.目前包含SharedPreferences Util, Screen Util, Directory Util, Widget Util, Image Util
flutter_barcode_scanner 扫描二维码
flutter_easyrefresh 下拉刷新
flutter_fai_webview 网页加载插件
flutter_launcher_icons 生成icon
flutter_local_notifications 消息推送
flutter_native_splash 生成闪屏页
flutter_neumorphic Neumorphic ui 新拟物
flutter_screenutil 屏幕适配
flutter_skeleton 骨架屏
flutter_sound 录音、播放
flutter_staggered_animations 快速添加交互动画
flutter_staggered_grid_view 强大的GridView,可实现瀑布流,单独设置每行显示的个数
flutter_swiper 轮播图
flutter_toast Toast
font_awesome_flutter Font Awesome图标库
fullscreen 全屏、沉浸
geolocator 获取GPS定位
get 高性能的状态管理、智能的依赖注入和便捷的路由管理
glassmorphism 玻璃态
image_gallery_saver 保存图片到本地相册
image_picker 拍照
install_plugin 让app拥有安装软件的功能
intl 提供国际化和本地化工具,包括消息翻译、复数和性别、日期/数字格式和解析以及双向文本
json_model JSON转Model对象
keyboard dismisser 隐藏软键盘
lottie 动画库
modal_bottom_sheet 第三方ModalBottomSheet
moor 数据库操作库
overlay_support 快速构建toast和通知
package_info App信息
palette_generator 获取图片的主色调
path 路径
path_provider 获取路径
permission_handler 权限请求(ios权限请求只能拒绝1次)
proste_indexed_stack 懒加载的IndexStack
provider 灵活的到处处理和传递数据
pull_to_refresh 提供给flutter scroll组件的下拉刷新和上拉加载的小部件
share 分享组件
shared_preferences 简单数据持久化,本地数据存储,存储键值集合
showcaseview 功能演示
sliding_up_panel 从下往上托的面板
sliver_tools Sliver组件的扩展工具
smooth_page_indicator 高级页面指示器
snapping_sheet 多样式的Sheet组件
sqlite 数据库存储
transparent_image 加载占位图
url_launcher 运行网页
webview 网页