本文汇总了 Flutter 开发中跨平台(iOS/Android)的常见实用技巧,包括插件桥接 OC 库、签名与 ADB 操作、自动方向监听及物理返回按键拦截等,方便快速查阅。
iOS
插件swift 调用oc库
project.podspec文件添加库依赖 s.dependency 'name', 'version'
如需桥接文件
Pods/Development Pods/project/../ios/Classes/目录下创建桥接文件Flutter-Bridging-Header.h,并引用库头文件
在project-umbrella.h文件中添加#import "Flutter-Bridging-Header.h"(也可以全局搜索ProjectPlugin.h后添加在其下)⚠️Podfile必须有use_framework!属性才会生成umbrella文件
如需要添加其他资源文件,需要在project.podspec中配置
1 2 3 4 5 6 7 8 search_paths = [ '${SDKROOT}/usr/include/libxml2' ] s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64', 'HEADER_SEARCH_PATHS' => search_paths.join(' '), }
进入Podfile所在目录pod install
如果调用iOS插件失败,则需要在Info.plist中添加以下代码
1 2 <key>io.flutter.embedded_views_preview</key> <true/>
Android
密钥 & adb
获取jks应用签名 keytool -list -v -keystore yourkeystore,选取对应别名的MD5: MD5.split(":").join("")
adb devices查看连接设备;adb -s serial指定设备连接;adb -s serial shell连接指定设备shell
Flutter
自动方向监听
添加每一帧回调方法
1 2 3 4 5 6 7 8 9 10 void addPersistentFrameCallback(VoidCallback cb) { final widgetsBinding = WidgetsBinding.instance; widgetsBinding.addPostFrameCallback((callback) { widgetsBinding.addPersistentFrameCallback((callback) { if (cb != null) cb(); //触发一帧的绘制 widgetsBinding.scheduleFrame(); }); }); }
在initState方法中初始化监听
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 addPersistentFrameCallback(() { var orientation = MediaQuery.of(videoContext).orientation; bool _fullscreen; if (orientation == Orientation.landscape) { //横屏 _fullscreen = true; SystemChrome.setEnabledSystemUIOverlays([]); } else if (orientation == Orientation.portrait) { _fullscreen = false; SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values); } if (_fullscreen != fullscreened) { setState(() { fullscreened = !fullscreened; //触发全屏事件 if (widget.onfullscreen != null) { widget.onfullscreen(fullscreened); } }); } });
拦截物理返回按键
WillPopScope,会拦截右滑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int last = 0; Future<bool> doubleClickBack() { int now = DateTime.now().millisecond; if (now - last > 800) { last = DateTime.now().millisecond; return Future.value(false); } else { return Future.value(true); } } WillPopScope( onWillPop: doubleClickBack, child: Widget );
弹出一个本地路由防止物理按键直接返回
1 2 3 4 5 6 7 8 9 10 11 void _navigateLocally(context) async { if (!fullscreened) { if (ModalRoute.of(context).willHandlePopInternally) { Navigator.of(context).pop(); } return; } ModalRoute.of(context).addLocalHistoryEntry(LocalHistoryEntry(onRemove: () { if (fullscreened) toggleFullScreen(); })); }
问题
升级Xcode11.4导致Flutter项目报错Building for iOS, but the linked and embedded framework 'App.framework’的处理
进入项目根目录
flutter clean
rm -rf ios/Flutter/App.framework