测试Demo
遇到问题欢迎提Issue, 共同进步
Plugin
的android/ios
的MyFlutterPlugin:MethodCallHandler
提供原生方法, 并定义ChannelName
:companion object { @JvmStatic fun registerWith(registrar: Registrar) { val channel = MethodChannel(registrar.messenger(), "统一的渠道名字") channel.setMethodCallHandler(MyFlutterPlugin(registrar.activity())) } }
Plugin
的flutter_plugin.dart
内获取到android/ios
内部内定的Channel
, 并暴露Plugin
方法 ( 类似于代理原生方法, 其实这也是plugin
的目的 ) :static const MethodChannel _channel = const MethodChannel('统一的渠道名字'); static Future<String> get goToOtherApp async { final String result = await _channel.invokeMethod('goToOtherApp'); return result; }
Plugin
的pubspec.yaml
文件标明此Plugin
的信息, 以供主项目引用flutter: plugin: androidPackage: com.youcii.flutter_plugin pluginClass: MyFlutterPlugin
- 主项目的
pubspec.yaml
中引用Plugin
, 名字可自定义:dev_dependencies: flutter_plugin: path: flutter_plugin
- 主项目的
android/ios
自动依赖到Plugin
的android/ios
( 通过主项目build.gradle
的merge
操作 ), 自动编译注册MyFlutterPlugin
(这一层无需任何手动操作):MyFlutterPlugin.registerWith(registry.registrarFor("com.youcii.flutter_plugin.MyFlutterPlugin"));
- 主项目调用
Plugin
内的原生方法时, 只需要以下操作:import 'package:flutter_plugin/flutter_plugin.dart'; // 必须异步调用 Future<void> _initPlatformState() async { try { _result = await FlutterPlugin.goToOtherApp; } on PlatformException { _result = 'Failed to get platform version.'; } setState(() { _result = _result; }); }
onCreate
:initState
或者didChangeDependencies
(后者更强大)onResume
:didPush
(从前一页面进入时),didPopNext
(从后一页面返回时)onPause
:didPushNext
(进入到后一页面前),didPop
(返回前一页面)onDestroy
:dispose
- 前后台切换:
didChangeAppLifecycleState
- 不允许在
factory
中引用当前类的示例; - 可以定义别名构造方法, 例如:
SingleObject.create();
- 如果显示声明某种形式的构造方法, 则只允许使用显示声明的构造形式;
SliverAppBar
: 实现类似Android#CollapsingToolbarLayout
的动画SliverGrid
: 组合Grid列表SliverPersistentHeader
: 可中间插入/固定在顶部/缩放的Header
SliverFixedExtentList
: 比SliverList
效果更高的组合列表(因为固定了item在主轴方向上的长度)
同步代码 > MicroTask Queue
> Event Queue
, 其中EventQueue
中的Event
包括:
- dart产生的事件: Future, Timer, Isolate之间的消息等;
- 系统产生的事件: I/O, 鼠标事件, 屏幕点击等;
- 继承
RenderObject
的子类RenderBox
更简单, 它在父类的基础上实现了笛卡尔坐标系, 更易用; - 如果不重写
isRepaintBoundary
为true或者用RepaintBoundary
包裹的话, 会出现offset偏移的情况; paint
方法中需要刷新一下修改的参数/或者修改变量时修改painter
参数, 才可以支持外部setState
时该参数的刷新;- 当
isRepaintBoundary
返回true时必须重写此方法去掉super, 否则红屏错误;@override void performLayout() { size = constraints.constrain(Size(_starSize, _starSize)); }
- 如果想要监听onTap就必须重写
hitTestSelf
然后按情况返回, 作为叶子widget时直接返回true; - 修改
RenderObject
的内部参数时, 记得在set方法中调用markNeedsPaint
或者markNeedsLayout
将其标为dirty
状态, 否则setState
不会更新它; - 使用
RenderObject
的LeafRenderObjectWidget
需要重写updateRenderObject
修改下UI关心的参数, 否则setState
不会更新这些参数; CustomPaint
和CustomPainter
也可以实现自定义效果, 但是细节有点差别;