Commit 7aaec780 authored by yangwu.jia's avatar yangwu.jia

Merge branch 'feature/base_flutter_1.12_upgrade' into...

Merge branch 'feature/base_flutter_1.12_upgrade' into feature/base_flutter_1.12_upgrade_for_androidx

# Conflicts:
#	android/build.gradle
#	example/android/app/build.gradle
#	ios/Classes/Boost/FlutterBoostPlugin.h
parents fe32e194 f008fd22
## 0.0.1 ## 0.1.66
* TODO: Describe initial release. Fixed bugs
## 0.1.5
The main changes are as following:
1. The new version do the page jump (URL route) based on the inherited FlutterViewController or Activity. The jump procedure will create new instance of FlutterView, while the old version just reuse the underlying FlutterView
2. Avoiding keeping and reusing the FlutterView, there is no screenshot and complex attach&detach logical any more. As a result, memory is saved and black or white-screen issue occured in old version all are solved.
3. This version also solved the app life cycle observation issue, we recommend you to use ContainerLifeCycle observer to listen the app enter background or foreground notification instead of WidgetBinding.
4. We did some code refactoring, the main logic became more straightforward.
## 0.1.64
Fixed bugs
## 0.1.63
android:
Fixed bugs
iOS:
no change
## 0.1.61
android:
Fixed bugs
iOS:
no change
## 0.1.60 ## 0.1.60
...@@ -30,21 +43,19 @@ ios: ...@@ -30,21 +43,19 @@ ios:
1.based on the v1.9.1+hotfixes branch of flutter 1.based on the v1.9.1+hotfixes branch of flutter
2.bugfixed 2.bugfixed
## 0.1.61
android:
Fixed bugs
iOS: ## 0.1.5
no change The main changes are as following:
1. The new version do the page jump (URL route) based on the inherited FlutterViewController or Activity. The jump procedure will create new instance of FlutterView, while the old version just reuse the underlying FlutterView
2. Avoiding keeping and reusing the FlutterView, there is no screenshot and complex attach&detach logical any more. As a result, memory is saved and black or white-screen issue occured in old version all are solved.
3. This version also solved the app life cycle observation issue, we recommend you to use ContainerLifeCycle observer to listen the app enter background or foreground notification instead of WidgetBinding.
4. We did some code refactoring, the main logic became more straightforward.
## 0.1.63 ## 0.0.1
android: * TODO: Describe initial release.
Fixed bugs
iOS:
no change
### API changes ### API changes
From the point of API changes, we did some refactoring as following: From the point of API changes, we did some refactoring as following:
......
### 在FlutterBoost下如何管理Flutter页面的生命周期?原生的Flutter的AppLifecycleState事件会不一致,比如ViewAppear会导致app状态suspending或者paused。混合栈怎么处理? ### 1. 在FlutterBoost下如何管理Flutter页面的生命周期?原生的Flutter的AppLifecycleState事件会不一致,比如ViewAppear会导致app状态suspending或者paused。混合栈怎么处理?
回答:在混合栈下,页面事件基于以下自定义的事件: 回答:在混合栈下,页面事件基于以下自定义的事件:
```dart ```dart
enum ContainerLifeCycle { enum ContainerLifeCycle {
...@@ -12,7 +12,7 @@ enum ContainerLifeCycle { ...@@ -12,7 +12,7 @@ enum ContainerLifeCycle {
} }
``` ```
对于页面事件重复,请参考下面的FAQ。 对于页面事件重复,请参考下面的FAQ。
### 如何判断flutter的widget或者container是当前可见的? ### 2. 如何判断flutter的widget或者container是当前可见的?
回答:有个api可以判断当前页面是否可见: 回答:有个api可以判断当前页面是否可见:
```dart ```dart
bool isTopContainer = FlutterBoost.BoostContainer.of(context).onstage bool isTopContainer = FlutterBoost.BoostContainer.of(context).onstage
...@@ -20,13 +20,25 @@ bool isTopContainer = FlutterBoost.BoostContainer.of(context).onstage ...@@ -20,13 +20,25 @@ bool isTopContainer = FlutterBoost.BoostContainer.of(context).onstage
传入你widget的context,就能判断你的widget是否是可见的 传入你widget的context,就能判断你的widget是否是可见的
基于这个API,可以判断你的widget是否可见,从而避免接收一些重复的生命周期消息。参考这个issue:https://github.com/alibaba/flutter_boost/issues/498 基于这个API,可以判断你的widget是否可见,从而避免接收一些重复的生命周期消息。参考这个issue:https://github.com/alibaba/flutter_boost/issues/498
### 您好,我想请教一下flutter_boost有关的问题:ABC三个都是flutter页面,从 A页面 -> B页面 -> C页面,当打开C页面时希望自动关掉B页面,当从C页面返回时直接返回A页面,可有什么方法? ### 3. 您好,我想请教一下flutter_boost有关的问题:ABC三个都是flutter页面,从 A页面 -> B页面 -> C页面,当打开C页面时希望自动关掉B页面,当从C页面返回时直接返回A页面,可有什么方法?
回答:你只需要操作Native层的UINavigationController里的vc数组就可以了。就如同平时你操作普通的UIViewController一样。因为FlutterBoost对Native层的FlutterViewController和Dart层的flutter page的生命周期管理是一致的,当FlutterViewController被销毁,其在dart层管理的flutter page也会自动被销毁。 回答:你只需要操作Native层的UINavigationController里的vc数组就可以了。就如同平时你操作普通的UIViewController一样。因为FlutterBoost对Native层的FlutterViewController和Dart层的flutter page的生命周期管理是一致的,当FlutterViewController被销毁,其在dart层管理的flutter page也会自动被销毁。
### 在ios中voice over打开,demo在点击交互会crash ### 4. 在ios中voice over打开,demo在点击交互会crash;
回答:无障碍模式下目前Flutter Engine有bug,已经提交issue和PR给flutter啦。请参考这个issue:https://github.com/alibaba/flutter_boost/issues/488及其分析。提交给flutter的PR见这里:https://github.com/flutter/engine/pull/14155 回答:无障碍模式下目前Flutter Engine有bug,已经提交issue和PR给flutter啦。请参考这个issue:https://github.com/alibaba/flutter_boost/issues/488及其分析。提交给flutter的PR见这里:https://github.com/flutter/engine/pull/14155
### 似乎官方已经提供了混合栈的功能,参考这里:https://flutter.dev/docs/development/add-to-app; FlutterBoost是否有存在的必要? ### 5. 在ios模拟器下运行最新的flutter boost会闪退
回答:因为模拟器下flutter默认会将voice over模式打开,所以其实就是辅助模式,这回触发上面的bug:“在ios中voice over打开,demo在点击交互会crash”。
可参考Engine的代码注释:
```c++
#if TARGET_OS_SIMULATOR
// There doesn't appear to be any way to determine whether the accessibility
// inspector is enabled on the simulator. We conservatively always turn on the
// accessibility bridge in the simulator, but never assistive technology.
platformView->SetSemanticsEnabled(true);
platformView->SetAccessibilityFeatures(flags);
```
### 6. 似乎官方已经提供了混合栈的功能,参考这里:https://flutter.dev/docs/development/add-to-app; FlutterBoost是否有存在的必要?
回答:官方的解决方案仅仅是在native侧对FlutterViewController和Flutterengine进行解耦,如此可以一个FlutterEngine切换不同的FlutterViewController或者Activity进行渲染。但其并未解决Native和Flutter页面混合的问题,无法保证两侧的页面生命周期一致。即使是Flutter官方针对这个问题也是建议使用FlutterBoost。 回答:官方的解决方案仅仅是在native侧对FlutterViewController和Flutterengine进行解耦,如此可以一个FlutterEngine切换不同的FlutterViewController或者Activity进行渲染。但其并未解决Native和Flutter页面混合的问题,无法保证两侧的页面生命周期一致。即使是Flutter官方针对这个问题也是建议使用FlutterBoost。
其差别主要有: 其差别主要有:
...@@ -44,3 +56,7 @@ bool isTopContainer = FlutterBoost.BoostContainer.of(context).onstage ...@@ -44,3 +56,7 @@ bool isTopContainer = FlutterBoost.BoostContainer.of(context).onstage
|是否已经支持到View级别混合 |N |N |N| |是否已经支持到View级别混合 |N |N |N|
同时FlutterBoost也提供了一次性创建混合工程的命令:flutterboot。代码参考:https://github.com/alibaba-flutter/flutter-boot 同时FlutterBoost也提供了一次性创建混合工程的命令:flutterboot。代码参考:https://github.com/alibaba-flutter/flutter-boot
### 如果我需要通过FlutterViewController再弹出一个新的但frame比较小的FlutterViewController,应该怎么实现?
回答:如果不加处理会遇到window大小变化的问题,但可以解决。具体可以参考这个issue:https://github.com/alibaba/flutter_boost/issues/435
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# Release Note # Release Note
Please checkout the release note for the latest 0.1.63 to see changes [0.1.63 release note](https://github.com/alibaba/flutter_boost/releases) Please checkout the release note for the latest 0.1.64 to see changes [0.1.64 release note](https://github.com/alibaba/flutter_boost/releases)
# FlutterBoost # FlutterBoost
A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.The philosophy of FlutterBoost is to use Flutter as easy as using a WebView. Managing Native pages and Flutter pages at the same time is non-trivial in an existing App. FlutterBoost takes care of page resolution for you. The only thing you need to care about is the name of the page(usually could be an URL).  A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.The philosophy of FlutterBoost is to use Flutter as easy as using a WebView. Managing Native pages and Flutter pages at the same time is non-trivial in an existing App. FlutterBoost takes care of page resolution for you. The only thing you need to care about is the name of the page(usually could be an URL). 
...@@ -22,12 +22,12 @@ You need to add Flutter to your project before moving on.The version of the flut ...@@ -22,12 +22,12 @@ You need to add Flutter to your project before moving on.The version of the flut
1. 0.1.50 is based on the flutter v1.5.4-hotfixes branch, android if other flutter versions or branches will compile incorrectly 1. 0.1.50 is based on the flutter v1.5.4-hotfixes branch, android if other flutter versions or branches will compile incorrectly
2. 0.1.51--0.1.54 is a bugfix for 0.1.50 2. 0.1.51--0.1.59 is a bugfix for 0.1.50
3. 0.1.60 is based on the flutter v1.9.1-hotfixes branch. Android does not support andriodx if other flutter branches will compile incorrectly 3. 0.1.60 is based on the flutter v1.9.1-hotfixes branch. Android does not support andriodx if other flutter branches will compile incorrectly
4. 0.1.61--0.1.62 is a bugfix for 0.1.60 4. 0.1.61--0.1.69 is a bugfix for 0.1.60
5. Statement of support for androidx 5. Statement of support for androidx
...@@ -52,7 +52,7 @@ support branch ...@@ -52,7 +52,7 @@ support branch
flutter_boost: flutter_boost:
git: git:
url: 'https://github.com/alibaba/flutter_boost.git' url: 'https://github.com/alibaba/flutter_boost.git'
ref: '0.1.63' ref: '0.1.64'
``` ```
androidx branch androidx branch
```json ```json
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# Release Note # Release Note
请查看最新版本0.1.63的release note 确认变更,[0.1.63 release note](https://github.com/alibaba/flutter_boost/releases) 请查看最新版本0.1.64的release note 确认变更,[0.1.64 release note](https://github.com/alibaba/flutter_boost/releases)
# FlutterBoost # FlutterBoost
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
3. 0.1.60 是基于flutter v1.9.1-hotfixes 分支,android如果其他flutter分支会编译错误,该版本不支持andriodx 3. 0.1.60 是基于flutter v1.9.1-hotfixes 分支,android如果其他flutter分支会编译错误,该版本不支持andriodx
4. 0.1.61-- 0.1.63 是对0.1.60 的bugfix 4. 0.1.61-- 0.1.64 是对0.1.60 的bugfix
5. 关于androidx 的支持声明 5. 关于androidx 的支持声明
...@@ -56,7 +56,7 @@ support分支 ...@@ -56,7 +56,7 @@ support分支
flutter_boost: flutter_boost:
git: git:
url: 'https://github.com/alibaba/flutter_boost.git' url: 'https://github.com/alibaba/flutter_boost.git'
ref: '0.1.63' ref: '0.1.64'
``` ```
......
...@@ -35,12 +35,12 @@ android { ...@@ -35,12 +35,12 @@ android {
} }
dependencies { dependencies {
implementation 'androidx.legacy:legacy-support-v4:1.0.0' compileOnly 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.0.0' compileOnly 'com.google.android.material:material:1.0.0'
implementation 'androidx.appcompat:appcompat:1.0.0' compileOnly 'androidx.appcompat:appcompat:1.0.0'
implementation 'androidx.annotation:annotation:1.0.0' compileOnly 'androidx.annotation:annotation:1.0.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.1.0' implementation 'androidx.lifecycle:lifecycle-common-java8:2.1.0'
implementation 'com.alibaba:fastjson:1.2.41' compileOnly 'com.alibaba:fastjson:1.2.41'
} }
......
...@@ -185,7 +185,8 @@ public class Utils { ...@@ -185,7 +185,8 @@ public class Utils {
} }
} }
}catch (Throwable t){ }catch (Throwable t){
Debuger.exception(t); // Debuger.exception(t);
t.printStackTrace();
} }
} }
......
...@@ -73,7 +73,7 @@ public class BoostFlutterActivity extends Activity ...@@ -73,7 +73,7 @@ public class BoostFlutterActivity extends Activity
private Map params = new HashMap(); private Map params = new HashMap();
protected NewEngineIntentBuilder(@NonNull Class<? extends BoostFlutterActivity> activityClass) { public NewEngineIntentBuilder(@NonNull Class<? extends BoostFlutterActivity> activityClass) {
this.activityClass = activityClass; this.activityClass = activityClass;
} }
......
...@@ -24,8 +24,26 @@ ...@@ -24,8 +24,26 @@
DF544AA72177253600931378 /* UIViewControllerDemo.xib in Resources */ = {isa = PBXBuildFile; fileRef = DF544AA52177253600931378 /* UIViewControllerDemo.xib */; }; DF544AA72177253600931378 /* UIViewControllerDemo.xib in Resources */ = {isa = PBXBuildFile; fileRef = DF544AA52177253600931378 /* UIViewControllerDemo.xib */; };
DF544AD4217838EF00931378 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DF544AD3217838EF00931378 /* libc++.tbd */; }; DF544AD4217838EF00931378 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DF544AD3217838EF00931378 /* libc++.tbd */; };
DFD80BFA217DF95400E3F036 /* PlatformRouterImp.m in Sources */ = {isa = PBXBuildFile; fileRef = DFD80BF9217DF95400E3F036 /* PlatformRouterImp.m */; }; DFD80BFA217DF95400E3F036 /* PlatformRouterImp.m in Sources */ = {isa = PBXBuildFile; fileRef = DFD80BF9217DF95400E3F036 /* PlatformRouterImp.m */; };
FA32AEF623B4A56E00449D68 /* NativeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA32AEF523B4A56D00449D68 /* NativeViewController.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
FA32AEEF23B4685B00449D68 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FA32AEEA23B4685A00449D68 /* products.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = EDB8DD4E9A4BE1510409988F;
remoteInfo = sources;
};
FA32AEF123B4686E00449D68 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FA32AEEA23B4685A00449D68 /* products.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 7EE23C83374079D8D3916ACE;
remoteInfo = All;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = { 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase; isa = PBXCopyFilesBuildPhase;
...@@ -68,6 +86,9 @@ ...@@ -68,6 +86,9 @@
DF544AD3217838EF00931378 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; DF544AD3217838EF00931378 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
DFD80BF8217DF95400E3F036 /* PlatformRouterImp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformRouterImp.h; sourceTree = "<group>"; }; DFD80BF8217DF95400E3F036 /* PlatformRouterImp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformRouterImp.h; sourceTree = "<group>"; };
DFD80BF9217DF95400E3F036 /* PlatformRouterImp.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlatformRouterImp.m; sourceTree = "<group>"; }; DFD80BF9217DF95400E3F036 /* PlatformRouterImp.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlatformRouterImp.m; sourceTree = "<group>"; };
FA32AEEA23B4685A00449D68 /* products.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = products.xcodeproj; path = ../../../engine_github/src/out/ios_debug_unopt/products.xcodeproj; sourceTree = "<group>"; };
FA32AEF423B4A56D00449D68 /* NativeViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NativeViewController.h; sourceTree = "<group>"; };
FA32AEF523B4A56D00449D68 /* NativeViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NativeViewController.m; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
...@@ -120,6 +141,7 @@ ...@@ -120,6 +141,7 @@
97C146E51CF9000F007C117D = { 97C146E51CF9000F007C117D = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FA32AEEA23B4685A00449D68 /* products.xcodeproj */,
9740EEB11CF90186004384FC /* Flutter */, 9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
...@@ -153,6 +175,8 @@ ...@@ -153,6 +175,8 @@
97C146F11CF9000F007C117D /* Supporting Files */, 97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
FA32AEF423B4A56D00449D68 /* NativeViewController.h */,
FA32AEF523B4A56D00449D68 /* NativeViewController.m */,
); );
path = Runner; path = Runner;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -165,6 +189,14 @@ ...@@ -165,6 +189,14 @@
name = "Supporting Files"; name = "Supporting Files";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
FA32AEEB23B4685A00449D68 /* Products */ = {
isa = PBXGroup;
children = (
FA32AEF023B4685B00449D68 /* sources */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
...@@ -180,11 +212,11 @@ ...@@ -180,11 +212,11 @@
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
3FC74F80EA9D039C70D1F681 /* [CP] Embed Pods Frameworks */, 3FC74F80EA9D039C70D1F681 /* [CP] Embed Pods Frameworks */,
D49B04E67D494964A3A713AC /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
dependencies = ( dependencies = (
FA32AEF223B4686E00449D68 /* PBXTargetDependency */,
); );
name = Runner; name = Runner;
productName = Runner; productName = Runner;
...@@ -218,6 +250,12 @@ ...@@ -218,6 +250,12 @@
mainGroup = 97C146E51CF9000F007C117D; mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */; productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = ""; projectDirPath = "";
projectReferences = (
{
ProductGroup = FA32AEEB23B4685A00449D68 /* Products */;
ProjectRef = FA32AEEA23B4685A00449D68 /* products.xcodeproj */;
},
);
projectRoot = ""; projectRoot = "";
targets = ( targets = (
97C146ED1CF9000F007C117D /* Runner */, 97C146ED1CF9000F007C117D /* Runner */,
...@@ -225,6 +263,16 @@ ...@@ -225,6 +263,16 @@
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXReferenceProxy section */
FA32AEF023B4685B00449D68 /* sources */ = {
isa = PBXReferenceProxy;
fileType = "compiled.mach-o.executable";
path = sources;
remoteRef = FA32AEEF23B4685B00449D68 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = { 97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
...@@ -262,8 +310,8 @@ ...@@ -262,8 +310,8 @@
files = ( files = (
); );
inputPaths = ( inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", "${PODS_ROOT}/../.symlinks/flutter/ios_debug_sim_unopt/Flutter.framework",
); );
name = "[CP] Embed Pods Frameworks"; name = "[CP] Embed Pods Frameworks";
outputPaths = ( outputPaths = (
...@@ -271,7 +319,7 @@ ...@@ -271,7 +319,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
9740EEB61CF901F6004384FC /* Run Script */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
...@@ -303,22 +351,7 @@ ...@@ -303,22 +351,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
D49B04E67D494964A3A713AC /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
...@@ -333,11 +366,20 @@ ...@@ -333,11 +366,20 @@
97C146F31CF9000F007C117D /* main.m in Sources */, 97C146F31CF9000F007C117D /* main.m in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
DF544AA62177253600931378 /* UIViewControllerDemo.m in Sources */, DF544AA62177253600931378 /* UIViewControllerDemo.m in Sources */,
FA32AEF623B4A56E00449D68 /* NativeViewController.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
FA32AEF223B4686E00449D68 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = All;
targetProxy = FA32AEF123B4686E00449D68 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */ /* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = { 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#import "AppDelegate.h" #import "AppDelegate.h"
#import "UIViewControllerDemo.h" #import "UIViewControllerDemo.h"
#import "PlatformRouterImp.h" #import "PlatformRouterImp.h"
#import "NativeViewController.h"
#import <flutter_boost/FlutterBoost.h> #import <flutter_boost/FlutterBoost.h>
@interface AppDelegate () @interface AppDelegate ()
...@@ -50,19 +51,19 @@ ...@@ -50,19 +51,19 @@
self.window.rootViewController = rvc; self.window.rootViewController = rvc;
UIButton *nativeButton = [UIButton buttonWithType:UIButtonTypeCustom]; UIButton *nativeButton = [UIButton buttonWithType:UIButtonTypeCustom];
nativeButton.frame = CGRectMake(self.window.frame.size.width * 0.5 - 50, 200, 100, 45); nativeButton.frame = CGRectMake(self.window.frame.size.width * 0.5 - 50, 200, 100, 40);
nativeButton.backgroundColor = [UIColor redColor]; nativeButton.backgroundColor = [UIColor redColor];
[nativeButton setTitle:@"push native" forState:UIControlStateNormal]; [nativeButton setTitle:@"push native" forState:UIControlStateNormal];
[nativeButton addTarget:self action:@selector(pushNative) forControlEvents:UIControlEventTouchUpInside]; [nativeButton addTarget:self action:@selector(pushNative) forControlEvents:UIControlEventTouchUpInside];
[self.window addSubview:nativeButton]; [self.window addSubview:nativeButton];
UIButton *pushEmbeded = [UIButton buttonWithType:UIButtonTypeCustom];
pushEmbeded.frame = CGRectMake(self.window.frame.size.width * 0.5 - 70, 150, 140, 40);
pushEmbeded.backgroundColor = [UIColor redColor];
[pushEmbeded setTitle:@"push embeded" forState:UIControlStateNormal];
[pushEmbeded addTarget:self action:@selector(pushEmbeded) forControlEvents:UIControlEventTouchUpInside];
[self.window addSubview:pushEmbeded];
return YES; return YES;
} }
...@@ -74,6 +75,12 @@ ...@@ -74,6 +75,12 @@
[nvc pushViewController:vc animated:YES]; [nvc pushViewController:vc animated:YES];
} }
- (void)pushEmbeded
{
UINavigationController *nvc = (id)self.window.rootViewController;
UIViewController *vc = [[NativeViewController alloc] init];
[nvc pushViewController:vc animated:YES];
}
- (void)applicationWillResignActive:(UIApplication *)application { - (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
......
//
// NativeViewController.h
// Runner
//
// Created by yujie on 2019/12/26.
// Copyright © 2019 The Chromium Authors. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface NativeViewController : UIViewController
@end
NS_ASSUME_NONNULL_END
//
// NativeViewController.m
// Runner
//
// Created by yujie on 2019/12/26.
// Copyright © 2019 The Chromium Authors. All rights reserved.
//
#import "NativeViewController.h"
#import <Flutter/Flutter.h>
#import <flutter_boost/FlutterBoost.h>
@interface NativeViewController ()
@property(nonatomic, strong)FLBFlutterViewContainer *flutterContainer;
@end
@implementation NativeViewController
- (instancetype)init{
if (self = [super init]) {
_flutterContainer = [[FLBFlutterViewContainer alloc]init];
[_flutterContainer setName:@"embeded" params:@{}];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor grayColor];
self.flutterContainer.view.frame = CGRectInset(self.view.bounds, 30, 100);
[self.view addSubview:self.flutterContainer.view];
[self addChildViewController:self.flutterContainer];
UIButton *nativeButton = [UIButton buttonWithType:UIButtonTypeCustom];
nativeButton.frame = CGRectMake(50,self.view.bounds.size.height-50,200,40);
nativeButton.backgroundColor = [UIColor blueColor];
[nativeButton setTitle:@"Button in Native" forState:UIControlStateNormal];
[nativeButton addTarget:self action:@selector(pushMe) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:nativeButton];
}
- (void)pushMe
{
UIViewController *vc = [[UIViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
//注意这行代码不可缺少
// [self.flutterContainer.view setNeedsLayout];
// [self.flutterContainer.view layoutIfNeeded];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
...@@ -17,6 +17,7 @@ class _MyAppState extends State<MyApp> { ...@@ -17,6 +17,7 @@ class _MyAppState extends State<MyApp> {
super.initState(); super.initState();
FlutterBoost.singleton.registerPageBuilders({ FlutterBoost.singleton.registerPageBuilders({
'embeded': (pageName, params, _)=>EmbededFirstRouteWidget(),
'first': (pageName, params, _) => FirstRouteWidget(), 'first': (pageName, params, _) => FirstRouteWidget(),
'second': (pageName, params, _) => SecondRouteWidget(), 'second': (pageName, params, _) => SecondRouteWidget(),
'tab': (pageName, params, _) => TabRouteWidget(), 'tab': (pageName, params, _) => TabRouteWidget(),
......
...@@ -26,6 +26,26 @@ class FirstRouteWidget extends StatelessWidget { ...@@ -26,6 +26,26 @@ class FirstRouteWidget extends StatelessWidget {
} }
} }
class EmbededFirstRouteWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
child: Text('Open second route'),
onPressed: () {
print("open second page!");
FlutterBoost.singleton.open("second").then((Map value) {
print(
"call me when page is finished. did recieve second route result $value");
});
},
),
),
);
}
}
class SecondRouteWidget extends StatelessWidget { class SecondRouteWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
......
...@@ -46,6 +46,7 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -46,6 +46,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)addUniqueViewController:(id<FLBFlutterContainer>)vc; - (void)addUniqueViewController:(id<FLBFlutterContainer>)vc;
- (void)removeViewController:(id<FLBFlutterContainer>)vc; - (void)removeViewController:(id<FLBFlutterContainer>)vc;
- (BOOL)isTop:(NSString *)pageId; - (BOOL)isTop:(NSString *)pageId;
- (NSInteger)pageCount;
#pragma mark - App Control #pragma mark - App Control
- (void)pause; - (void)pause;
......
...@@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)addUnique:(id<FLBFlutterContainer>)vc; - (void)addUnique:(id<FLBFlutterContainer>)vc;
- (void)remove:(id<FLBFlutterContainer>)vc; - (void)remove:(id<FLBFlutterContainer>)vc;
- (BOOL)contains:(id<FLBFlutterContainer>)vc; - (BOOL)contains:(id<FLBFlutterContainer>)vc;
- (NSInteger)pageCount;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
...@@ -79,6 +79,10 @@ ...@@ -79,6 +79,10 @@
return _idStk.lastObject; return _idStk.lastObject;
} }
- (NSInteger)pageCount{
return _idStk.count;
}
#if DEBUG #if DEBUG
- (void)dump:(NSString*)flag{ - (void)dump:(NSString*)flag{
NSMutableString *log = [[NSMutableString alloc]initWithFormat:@"[DEBUG]--%@--PageStack uid/name", flag]; NSMutableString *log = [[NSMutableString alloc]initWithFormat:@"[DEBUG]--%@--PageStack uid/name", flag];
......
...@@ -31,6 +31,12 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -31,6 +31,12 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Initializer #pragma mark - Initializer
+ (instancetype)sharedInstance; + (instancetype)sharedInstance;
/**
* 获取当前管理的页面栈中页面的个数
*
*/
+ (NSInteger)pageCount;
/** /**
* 初始化FlutterBoost混合栈环境。应在程序使用混合栈之前调用。如在AppDelegate中。本函数默认需要flutter boost来注册所有插件。 * 初始化FlutterBoost混合栈环境。应在程序使用混合栈之前调用。如在AppDelegate中。本函数默认需要flutter boost来注册所有插件。
* *
...@@ -130,5 +136,12 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -130,5 +136,12 @@ NS_ASSUME_NONNULL_BEGIN
exts:(NSDictionary *)exts exts:(NSDictionary *)exts
onPageFinished:(void (^)(NSDictionary *))resultCallback onPageFinished:(void (^)(NSDictionary *))resultCallback
completion:(void (^)(BOOL))completion; completion:(void (^)(BOOL))completion;
//切记:在destroyPluginContext前务必将所有FlutterViewController及其子类的实例销毁。在这里是FLBFlutterViewContainer。否则会异常;以下是全部步骤
//1. 首先通过为所有FlutterPlugin的methodChannel属性设为nil来解除其与FlutterEngine的间接强引用
//2. 销毁所有的FlutterViewController实例(或保证所有FlutterVC已经退出),来解除其与FlutterEngine的强引用,在每个VC卸载的时候FlutterEngine会调用destroyContext
//3. 调用FlutterBoostPlugin.destroyPluginContext函数来解除与其内部context的强引用。内部持有的FlutterEngine也会被卸载(非外部传入的情形)
//4. 如果是外部传入的FlutterEngine,需要外部自己释放
- (void)destroyPluginContext;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
...@@ -111,6 +111,11 @@ ...@@ -111,6 +111,11 @@
return _instance; return _instance;
} }
+ (NSInteger)pageCount{
id<FLBFlutterApplicationInterface> app = [[FlutterBoostPlugin sharedInstance] application];
return [app pageCount];
}
- (void)startFlutterWithPlatform:(id<FLBPlatform>)platform - (void)startFlutterWithPlatform:(id<FLBPlatform>)platform
onStart:(void (^)(FlutterEngine *engine))callback; onStart:(void (^)(FlutterEngine *engine))callback;
{ {
...@@ -138,8 +143,8 @@ ...@@ -138,8 +143,8 @@
__weak __typeof__(self) weakSelf = self; __weak __typeof__(self) weakSelf = self;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
__strong __typeof__(weakSelf) self = weakSelf; __strong __typeof__(weakSelf) self = weakSelf;
self.factory = FLBFactory.new; FLBFactory *factory = FLBFactory.new;
self.application = [self->_factory createApplication:platform]; self.application = [factory createApplication:platform];
[self.application startFlutterWithPlatform:platform [self.application startFlutterWithPlatform:platform
withEngine:engine withEngine:engine
withPluginRegisterred:registerPlugin withPluginRegisterred:registerPlugin
...@@ -191,4 +196,9 @@ ...@@ -191,4 +196,9 @@
id<FLBFlutterApplicationInterface> app = [[FlutterBoostPlugin sharedInstance] application]; id<FLBFlutterApplicationInterface> app = [[FlutterBoostPlugin sharedInstance] application];
[app close:uniqueId result:resultData exts:exts completion:completion]; [app close:uniqueId result:resultData exts:exts completion:completion];
} }
- (void)destroyPluginContext{
self.methodChannel = nil;
self.application = nil;
}
@end @end
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#import "FlutterBoostPlugin.h" #import "FlutterBoostPlugin.h"
@interface FlutterBoostPlugin() @interface FlutterBoostPlugin()
@property (nonatomic,strong) id<FLBFlutterApplicationInterface> application; @property (nonatomic,strong) id<FLBFlutterApplicationInterface> application;
@property (nonatomic,strong) id<FLBAbstractFactory> factory;
@property (nonatomic,strong) FlutterMethodChannel *methodChannel; @property (nonatomic,strong) FlutterMethodChannel *methodChannel;
@property (nonatomic,copy) NSString *fPageId; @property (nonatomic,copy) NSString *fPageId;
@property (nonatomic,copy) NSString *fPagename; @property (nonatomic,copy) NSString *fPagename;
......
...@@ -127,6 +127,9 @@ ...@@ -127,6 +127,9 @@
return [_manager remove:vc]; return [_manager remove:vc];
} }
- (NSInteger)pageCount{
return [_manager pageCount];
}
- (BOOL)isTop:(NSString *)pageId - (BOOL)isTop:(NSString *)pageId
{ {
......
...@@ -97,11 +97,6 @@ ...@@ -97,11 +97,6 @@
arguments:@{@"type":@"foreground"}]; arguments:@{@"type":@"foreground"}];
} }
- (FlutterEngine *)engine
{
return _engine;
}
- (void)atacheToViewController:(FlutterViewController *)vc - (void)atacheToViewController:(FlutterViewController *)vc
{ {
if(_engine.viewController != vc){ if(_engine.viewController != vc){
...@@ -124,5 +119,8 @@ ...@@ -124,5 +119,8 @@
// [self detach]; // [self detach];
} }
- (void)dealloc{
[self.engine setViewController:nil];
}
@end @end
...@@ -31,6 +31,5 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -31,6 +31,5 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic,copy,readwrite) NSString *name; @property (nonatomic,copy,readwrite) NSString *name;
- (instancetype)init NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_DESIGNATED_INITIALIZER;
- (void)surfaceUpdated:(BOOL)appeared; - (void)surfaceUpdated:(BOOL)appeared;
- (void)setEnableForRunnersBatch:(BOOL)enable;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
...@@ -158,11 +158,6 @@ static NSUInteger kInstanceCounter = 0; ...@@ -158,11 +158,6 @@ static NSUInteger kInstanceCounter = 0;
[FLUTTER_APP.flutterProvider detach]; [FLUTTER_APP.flutterProvider detach];
} }
- (void)setEnableForRunnersBatch:(BOOL)enable{
//dummy function
NSLog(@"[DEBUG]- I did nothing, I am innocent");
}
#pragma mark - Life circle methods #pragma mark - Life circle methods
- (void)viewDidLayoutSubviews - (void)viewDidLayoutSubviews
...@@ -188,6 +183,7 @@ static NSUInteger kInstanceCounter = 0; ...@@ -188,6 +183,7 @@ static NSUInteger kInstanceCounter = 0;
} }
[super viewWillAppear:animated]; [super viewWillAppear:animated];
[self.view setNeedsLayout];
//instead of calling [super viewWillAppear:animated];, call super's super //instead of calling [super viewWillAppear:animated];, call super's super
// struct objc_super target = { // struct objc_super target = {
// .super_class = class_getSuperclass([FlutterViewController class]), // .super_class = class_getSuperclass([FlutterViewController class]),
......
...@@ -80,6 +80,8 @@ class ContainerManagerState extends State<BoostContainerManager> { ...@@ -80,6 +80,8 @@ class ContainerManagerState extends State<BoostContainerManager> {
//Number of containers. //Number of containers.
int get containerCounts => _offstage.length; int get containerCounts => _offstage.length;
List<BoostContainer> get offstage => _offstage;
//Setting for current visible container. //Setting for current visible container.
BoostContainerSettings get onstageSettings => _onstage.settings; BoostContainerSettings get onstageSettings => _onstage.settings;
......
...@@ -44,7 +44,6 @@ typedef void PostPushRoute( ...@@ -44,7 +44,6 @@ typedef void PostPushRoute(
String url, String uniqueId, Map params, Route route, Future result); String url, String uniqueId, Map params, Route route, Future result);
class FlutterBoost { class FlutterBoost {
static final FlutterBoost _instance = FlutterBoost(); static final FlutterBoost _instance = FlutterBoost();
final GlobalKey<ContainerManagerState> containerManagerKey = final GlobalKey<ContainerManagerState> containerManagerKey =
GlobalKey<ContainerManagerState>(); GlobalKey<ContainerManagerState>();
...@@ -56,31 +55,38 @@ class FlutterBoost { ...@@ -56,31 +55,38 @@ class FlutterBoost {
static ContainerManagerState get containerManager => static ContainerManagerState get containerManager =>
_instance.containerManagerKey.currentState; _instance.containerManagerKey.currentState;
static void onPageStart() {
WidgetsBinding.instance.addPostFrameCallback((_) {
singleton.channel.invokeMethod<Map>('pageOnStart').then((Map pageInfo) {
if (pageInfo == null || pageInfo.isEmpty) return;
if (pageInfo.containsKey("name") &&
pageInfo.containsKey("params") &&
pageInfo.containsKey("uniqueId")) {
ContainerCoordinator.singleton.nativeContainerDidShow(
pageInfo["name"], pageInfo["params"], pageInfo["uniqueId"]);
}
});
});
}
static TransitionBuilder init( static TransitionBuilder init(
{TransitionBuilder builder, {TransitionBuilder builder,
PrePushRoute prePush, PrePushRoute prePush,
PostPushRoute postPush}) { PostPushRoute postPush}) {
if (Platform.isAndroid) {
if(Platform.isAndroid){ onPageStart();
WidgetsBinding.instance.addPostFrameCallback((_){
singleton.channel.invokeMethod<Map>('pageOnStart').then((Map pageInfo){
if (pageInfo == null || pageInfo.isEmpty) return;
if (pageInfo.containsKey("name") &&
pageInfo.containsKey("params") &&
pageInfo.containsKey("uniqueId")) {
ContainerCoordinator.singleton.nativeContainerDidShow(
pageInfo["name"], pageInfo["params"], pageInfo["uniqueId"]);
}
});
});
} }
assert(() {
() async {
if (Platform.isIOS) {
onPageStart();
}
}();
return true;
}());
return (BuildContext context, Widget child) { return (BuildContext context, Widget child) {
assert(child is Navigator, 'child must be Navigator, what is wrong?'); assert(child is Navigator, 'child must be Navigator, what is wrong?');
...@@ -102,7 +108,7 @@ class FlutterBoost { ...@@ -102,7 +108,7 @@ class FlutterBoost {
BoostChannel get channel => _boostChannel; BoostChannel get channel => _boostChannel;
FlutterBoost(){ FlutterBoost() {
ContainerCoordinator(_boostChannel); ContainerCoordinator(_boostChannel);
} }
...@@ -116,30 +122,29 @@ class FlutterBoost { ...@@ -116,30 +122,29 @@ class FlutterBoost {
ContainerCoordinator.singleton.registerPageBuilders(builders); ContainerCoordinator.singleton.registerPageBuilders(builders);
} }
Future<Map<dynamic,dynamic>> open(String url,{Map<dynamic,dynamic> urlParams,Map<dynamic,dynamic> exts}){ Future<Map<dynamic, dynamic>> open(String url,
{Map<dynamic, dynamic> urlParams, Map<dynamic, dynamic> exts}) {
Map<dynamic, dynamic> properties = new Map<dynamic, dynamic>(); Map<dynamic, dynamic> properties = new Map<dynamic, dynamic>();
properties["url"] = url; properties["url"] = url;
properties["urlParams"] = urlParams; properties["urlParams"] = urlParams;
properties["exts"] = exts; properties["exts"] = exts;
return channel.invokeMethod<Map<dynamic,dynamic>>( return channel.invokeMethod<Map<dynamic, dynamic>>('openPage', properties);
'openPage', properties);
} }
Future<bool> close(String id,{Map<dynamic,dynamic> result,Map<dynamic,dynamic> exts}){ Future<bool> close(String id,
{Map<dynamic, dynamic> result, Map<dynamic, dynamic> exts}) {
assert(id != null); assert(id != null);
BoostContainerSettings settings = containerManager?.onstageSettings; BoostContainerSettings settings = containerManager?.onstageSettings;
Map<dynamic, dynamic> properties = new Map<dynamic, dynamic>(); Map<dynamic, dynamic> properties = new Map<dynamic, dynamic>();
if(exts == null){ if (exts == null) {
exts = Map<dynamic,dynamic>(); exts = Map<dynamic, dynamic>();
} }
exts["params"] = settings.params; exts["params"] = settings.params;
if(!exts.containsKey("animated")){ if (!exts.containsKey("animated")) {
exts["animated"] = true; exts["animated"] = true;
} }
...@@ -155,28 +160,30 @@ class FlutterBoost { ...@@ -155,28 +160,30 @@ class FlutterBoost {
return channel.invokeMethod<bool>('closePage', properties); return channel.invokeMethod<bool>('closePage', properties);
} }
Future<bool> closeCurrent({Map<String,dynamic> result,Map<String,dynamic> exts}) { Future<bool> closeCurrent(
{Map<String, dynamic> result, Map<String, dynamic> exts}) {
BoostContainerSettings settings = containerManager?.onstageSettings; BoostContainerSettings settings = containerManager?.onstageSettings;
if(exts == null){ if (exts == null) {
exts = Map<String,dynamic>(); exts = Map<String, dynamic>();
} }
exts["params"] = settings.params; exts["params"] = settings.params;
if(!exts.containsKey("animated")){ if (!exts.containsKey("animated")) {
exts["animated"] = true; exts["animated"] = true;
} }
return close(settings.uniqueId,result: result,exts: exts); return close(settings.uniqueId, result: result, exts: exts);
} }
Future<bool> closeByContext(BuildContext context,{Map<String,dynamic> result,Map<String,dynamic> exts}) { Future<bool> closeByContext(BuildContext context,
{Map<String, dynamic> result, Map<String, dynamic> exts}) {
BoostContainerSettings settings = containerManager?.onstageSettings; BoostContainerSettings settings = containerManager?.onstageSettings;
if(exts == null){ if (exts == null) {
exts = Map<String,dynamic>(); exts = Map<String, dynamic>();
} }
exts["params"] = settings.params; exts["params"] = settings.params;
if(!exts.containsKey("animated")){ if (!exts.containsKey("animated")) {
exts["animated"] = true; exts["animated"] = true;
} }
return close(settings.uniqueId,result: result,exts: exts); return close(settings.uniqueId, result: result, exts: exts);
} }
///register for Container changed callbacks ///register for Container changed callbacks
......
name: flutter_boost name: flutter_boost
description: A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts. description: A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.
version: 0.1.63 version: 0.1.66
author: Alibaba Xianyu author: Alibaba Xianyu
homepage: https://github.com/alibaba/flutter_boost homepage: https://github.com/alibaba/flutter_boost
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment