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 路由管理

awesome_notifications 本地通知

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 高级页面指示器

smooth_star_rating 评星

snapping_sheet 多样式的Sheet组件

sqlite 数据库存储

transparent_image 加载占位图

url_launcher 运行网页

webview 网页

posted @ 2022-04-07 16:32  菠萝橙子丶  阅读(952)  评论(0编辑  收藏  举报