diff --git a/Frequently Asked Question.md b/Frequently Asked Question.md index acb6a498789813fa8f58c97ce1e831a45f5da568..cd6a67246bef440e0d5952627bf53370922a8fcf 100644 --- a/Frequently Asked Question.md +++ b/Frequently Asked Question.md @@ -30,7 +30,7 @@ bool isTopContainer = FlutterBoost.BoostContainer.of(context).onstage 回ç”ï¼šæ— éšœç¢æ¨¡å¼ä¸‹ç›®å‰Flutter Engine有bugï¼Œå·²ç»æäº¤issueå’ŒPRç»™flutter啦。请å‚考这个issue:https://github.com/alibaba/flutter_boost/issues/488åŠå…¶åˆ†æžã€‚æäº¤ç»™flutterçš„PRè§è¿™é‡Œï¼šhttps://github.com/flutter/engine/pull/14155 ### 5. 在ios模拟器下è¿è¡Œæœ€æ–°çš„flutter boost会闪退 -回ç”:如上é¢ç¬¬4æ¡æ‰€è¯´çš„,最新的flutter engine在voice over下有bug,会导致crashã€‚å› ä¸ºæ¨¡æ‹Ÿå™¨ä¸‹flutter默认会将voice overæ¨¡å¼æ‰“开,所以其实就是辅助模å¼ï¼Œè¿™å›žè§¦å‘上é¢çš„bug:“在iosä¸voice over打开,demo在点击交互会crashâ€ã€‚ +回ç”:如上é¢ç¬¬4æ¡æ‰€è¯´çš„,最新的flutter engine在voice over下有bug,会导致crashã€‚å› ä¸ºæ¨¡æ‹Ÿå™¨ä¸‹flutter默认会将voice overæ¨¡å¼æ‰“开,所以其实就是辅助模å¼ï¼Œè¿™ä¼šè§¦å‘上é¢çš„bug:“在iosä¸voice over打开,demo在点击交互会crashâ€ã€‚ å¯å‚考Engineçš„ä»£ç æ³¨é‡Šï¼š ```c++ #if TARGET_OS_SIMULATOR diff --git a/INTEGRATION.md b/INTEGRATION.md new file mode 100644 index 0000000000000000000000000000000000000000..79d62889e3501dcabe893ecb7b453cc86f04b477 --- /dev/null +++ b/INTEGRATION.md @@ -0,0 +1,170 @@ +1ã€ä¸ºä½•使用flutter_boost? + + å®˜æ–¹çš„é›†æˆæ–¹æ¡ˆæœ‰è¯¸å¤šå¼Šç—…: + - 日志ä¸èƒ½è¾“出到原生端; + - å˜åœ¨å†…å˜æ³„æ¼çš„问题,使用boostå¯ä»¥è®©å†…å˜ç¨³å®šï¼› + - native调用flutter,flutter调用native,通é“çš„å°è£…ï¼Œä½¿å¼€å‘æ›´åŠ ç®€ä¾¿ï¼› + - åŒæ—¶å¯¹äºŽé¡µé¢ç”Ÿå‘½å‘¨æœŸçš„管ç†ï¼Œä¹Ÿæ¢³ç†çš„æ¯”è¾ƒæ•´é½ + +2ã€é›†æˆæµç¨‹IOS + + +在delegateä¸åšflutteråˆå§‹åŒ–的工作 +``` + +在appDelegateä¸å¼•入,PlatformRouterImp,用于实现平å°ä¾§çš„页颿‰“开和关é—,ä¸å»ºè®®ç›´æŽ¥ä½¿ç”¨ç”¨äºŽé¡µé¢æ‰“开,建议使用FlutterBoostPluginä¸çš„openå’Œcloseæ–¹æ³•æ¥æ‰“开或关é—页é¢ï¼› +PlatformRouterImp内部实现打开å„ç§native页é¢çš„æ˜ 射。 + + self.router = [PlatformRouterImp new]; + //åˆå§‹åŒ–FlutterBoostæ··åˆæ ˆçŽ¯å¢ƒã€‚åº”åœ¨ç¨‹åºä½¿ç”¨æ··åˆæ ˆä¹‹å‰è°ƒç”¨ã€‚如在AppDelegateä¸ã€‚本函数默认需è¦flutter boostæ¥æ³¨å†Œæ‰€æœ‰æ’件。 + [FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:self.router + onStart:^(FlutterEngine *engine) { + + }]; + +``` +PlatformRouterImp,内部实现打开native页é¢çš„è·¯ç”±ä»£ç æˆªå›¾ + +``` +- (void)open:(NSString *)name + urlParams:(NSDictionary *)params + exts:(NSDictionary *)exts + completion:(void (^)(BOOL))completion +{ + if ([name isEqualToString:@"page1"]) {//打开页é¢1 + // 打开页é¢1çš„vc + return; + } + + BOOL animated = [exts[@"animated"] boolValue]; + FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new; + [vc setName:name params:params]; + [self.navigationController pushViewController:vc animated:animated]; + if(completion) completion(YES); +} +``` +如何打开,关é—flutter页é¢ï¼Œç›´æŽ¥è°ƒç”¨FlutterBoostPlugin的类方法å³å¯ã€‚ + +``` + +/** + * å…³é—页é¢ï¼Œæ··åˆæ ˆæŽ¨è使用的用于æ“作页é¢çš„æŽ¥å£ + * + * @param uniqueId å…³é—的页é¢å”¯ä¸€ID符 + * @param resultData 页é¢è¦è¿”回的结果(给上一个页é¢ï¼‰ï¼Œä¼šä½œä¸ºé¡µé¢è¿”å›žå‡½æ•°çš„å›žè°ƒå‚æ•° + * @param exts é¢å¤–傿•° + * @param completion å…³é—页é¢çš„峿—¶å›žè°ƒï¼Œé¡µé¢ä¸€æ—¦å…³é—å³å›žè°ƒ + */ ++ (void)close:(NSString *)uniqueId + result:(NSDictionary *)resultData + exts:(NSDictionary *)exts + completion:(void (^)(BOOL))completion; + +/** + * 打开新页é¢ï¼ˆé»˜è®¤ä»¥pushæ–¹å¼ï¼‰ï¼Œæ··åˆæ ˆæŽ¨è使用的用于æ“作页é¢çš„æŽ¥å£ï¼›é€šè¿‡urlParamså¯ä»¥è®¾ç½®ä¸ºä»¥presentæ–¹å¼æ‰“开页é¢ï¼šurlParams:@{@"present":@(YES)} + * + * @param url 打开的页é¢èµ„æºå®šä½ç¬¦ + * @param urlParams ä¼ äººé¡µé¢çš„傿•°; 若有特殊逻辑,å¯ä»¥é€šè¿‡è¿™ä¸ªå‚数设置回调的id + * @param exts é¢å¤–傿•° + * @param resultCallback 当页é¢ç»“æŸè¿”回时执行的回调,通过这个回调å¯ä»¥å–得页é¢çš„返回数æ®ï¼Œå¦‚closeå‡½æ•°ä¼ å…¥çš„resultData + * @param completion 打开页é¢çš„峿—¶å›žè°ƒï¼Œé¡µé¢ä¸€æ—¦æ‰“å¼€å³å›žè°ƒ + */ ++ (void)open:(NSString *)url + urlParams:(NSDictionary *)urlParams + exts:(NSDictionary *)exts + onPageFinished:(void (^)(NSDictionary *))resultCallback + completion:(void (^)(BOOL))completion; + +/** + * Presentæ–¹å¼æ‰“开新页é¢ï¼Œæ··åˆæ ˆæŽ¨è使用的用于æ“作页é¢çš„æŽ¥å£ + * + * @param url 打开的页é¢èµ„æºå®šä½ç¬¦ + * @param urlParams ä¼ äººé¡µé¢çš„傿•°; 若有特殊逻辑,å¯ä»¥é€šè¿‡è¿™ä¸ªå‚数设置回调的id + * @param exts é¢å¤–傿•° + * @param resultCallback 当页é¢ç»“æŸè¿”回时执行的回调,通过这个回调å¯ä»¥å–得页é¢çš„返回数æ®ï¼Œå¦‚closeå‡½æ•°ä¼ å…¥çš„resultData + * @param completion 打开页é¢çš„峿—¶å›žè°ƒï¼Œé¡µé¢ä¸€æ—¦æ‰“å¼€å³å›žè°ƒ + */ ++ (void)present:(NSString *)url + urlParams:(NSDictionary *)urlParams + exts:(NSDictionary *)exts +onPageFinished:(void (^)(NSDictionary *))resultCallback + completion:(void (^)(BOOL))completion; +``` + +IOSå¦‚ä½•ä¼ é€’æ•°æ®ç»™flutter + +``` +//name是事件的å称,arguments䏿˜¯ä¸€ä¸ªNSDictionary,OC代ç +[FlutterBoostPlugin.sharedInstance sendEvent:@"name" arguments:@{}]; + +//flutter部分接收数æ®ï¼Œdart代ç + FlutterBoost.singleton.channel.addEventListener('name', + (name, arguments){ + //todo + + return; + }); +``` + +flutterå¦‚ä½•ä¼ é€’æ•°æ®ç»™native + +``` +//flutter代ç ,ChannelName是通é“å称与native部分一致å³å¯ï¼Œtmp是mapç±»åž‹çš„å‚æ•° + Map<String,dynamic> tmp = Map<String,dynamic>(); + + try{ + + FlutterBoost.singleton.channel.sendEvent(ChannelName, tmp); + + }catch(e){ + + + } + + +//IOS侧代ç + [FlutterBoostPlugin.sharedInstance addEventListener:^(NSString *name, NSDictionary *arguments) { + + + } forName:@"statistic"]; +``` + + +flutterä¸é¡µé¢çš„ç”Ÿå‘½å‘¨æœŸç®¡ç† + + +``` +enum ContainerLifeCycle { + Init, + Appear,//å·²ç»å‡ºçŽ°ï¼Œå¾ˆé—æ†¾çš„æ˜¯å¦‚果在native部分present页é¢ï¼Œè¿™é‡Œæ˜¯ä¸ä¼šå›žè°ƒçš„。 + WillDisappear, + Disappear, + Destroy, + Background, + Foreground +} + + + + FlutterBoost.singleton.addBoostContainerLifeCycleObserver(//这个类是å•ä¾‹ï¼Œå†æ¯ä¸ªé¡µé¢çš„initStateæ–¹æ³•ä¸æ·»åŠ å³å¯ç›‘å¬ + (ContainerLifeCycle state, BoostContainerSettings settings) { + //setttings是é…置,name表示页é¢çš„å称,建议一定è¦ç‰åˆ°å½“å‰é¡µé¢Appear状æ€çš„æ—¶å€™å†åšæ“作, + print( + 'FlutterBoost.singleton.addBoostContainerLifeCycleObserver '+state.toString()+' '+settings.name); + }, + ); +``` +关于flutter部分打开新页é¢çš„回调的一些å‘。 + +``` + FlutterBoost.singleton + .open(CoursePage.routeName, urlParams: { + + }).then((Map<dynamic, dynamic> value) { + print( + 'call me when page is finished. did recieve second route result $value'); + + //这个方法会优先于addBoostContainerLifeCycleObserverä¸çš„appear方法调用,所以说有些方法在这里调用,如果appear还没有出现的è¯å°±ä¼šæœ‰é—®é¢˜ã€‚ + }); +``` +3ã€é›†æˆæµç¨‹Android(待补充) \ No newline at end of file diff --git a/README.md b/README.md index fe5a18d81153afaadbf989066858d325242faa12..fce82a85b8dad3fe8e9bb90898ebd2dc28f1a8b3 100755 --- a/README.md +++ b/README.md @@ -5,18 +5,19 @@ <b></b><br> <a href="README_CN.md">䏿–‡æ–‡æ¡£</a> <a href="https://mp.weixin.qq.com/s?__biz=MzU4MDUxOTI5NA==&mid=2247484367&idx=1&sn=fcbc485f068dae5de9f68d52607ea08f&chksm=fd54d7deca235ec86249a9e3714ec18be8b2d6dc580cae19e4e5113533a6c5b44dfa5813c4c3&scene=0&subscene=131&clicktime=1551942425&ascene=7&devicetype=android-28&version=2700033b&nettype=ctnet&abtest_cookie=BAABAAoACwASABMABAAklx4AVpkeAMSZHgDWmR4AAAA%3D&lang=zh_CN&pass_ticket=1qvHqOsbLBHv3wwAcw577EHhNjg6EKXqTfnOiFbbbaw%3D&wx_header=1">䏿–‡ä»‹ç»</a> + <a href="INTEGRATION.md">集æˆç›¸å…³</a> </p> # Release Note -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) +Please checkout the release note for the latest 1.12.13+1 to see changes [1.12.13+1 release note](https://github.com/alibaba/flutter_boost/releases) # 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 name="bf647454"></a> # Prerequisites -You need to add Flutter to your project before moving on.The version of the flutter SDK requires v1.9.1+hotfixes, or it will compile error. +You need to add Flutter to your project before moving on.The version of the flutter SDK requires to match boost's version, or it will compile error. @@ -24,13 +25,8 @@ You need to add Flutter to your project before moving on.The version of the flut | Flutter Boost Version | Support Flutter SDK Version | Description | Support AndroidX? | | --------------------- | --------------------------- | ------------------------------------------------------------ | ------------------ | -| 0.1.50 | 1.5.4-hotfixes | android if other flutter versions or branches will compile incorrectly. | No | -| 0.1.51-0.1.59 | 1.5.4-hotfixes | bugfix for 0.1.50. | No | -| 0.1.60 | 1.9.1-hotfixes | Android does not support andriodx if other flutter branches will compile incorrectly. | No | -| 0.1.61-0.1.69 | 1.9.1-hotfixes | bugfix for 0.1.60. | No | -| 0.1.63 | 1.9.1-hotfixes | If other branches will compile incorrectly. Synchronize with the 0.1.60 code, and bugfix also merge to this branch. | No | | 1.9.1+2 | 1.9.1-hotfixes | Rename the version number and start supporting androidx by default | Yes | -| 1.12.13 | 1.12.13-hotfixes | supporting androidx | Yes | +| 1.12.13+1 | 1.12.13-hotfixes | supporting androidx | Yes | @@ -39,10 +35,7 @@ You need to add Flutter to your project before moving on.The version of the flut | Flutter Boost branch | Support Flutter SDK Version | Description | Support AndroidX? | | --------------------- | --------------------------- | ------------------------------------------------------------ | ------------------ | | v1.9.1-hotfixes | 1.9.1-hotfixes | for androidx | Yes | -| task/task_v1.9.1_support_hotfixes| 1.9.1-hotfixes | for support | NO | | v1.12.13-hotfixes | 1.12.13-hotfixes | for androidx | Yes | -| task/task_v1.12.13_support_hotfixes| 1.12.13-hotfixes | for support | NO | - # Getting Started @@ -56,14 +49,7 @@ androidx branch flutter_boost: git: url: 'https://github.com/alibaba/flutter_boost.git' - ref: ' 1.12.13' -``` -support branch -```json -flutter_boost: - git: - url: 'https://github.com/alibaba/flutter_boost.git' - ref: 'task/task_v1.12.13_support_hotfixes' + ref: '1.12.13+1' ``` diff --git a/README_CN.md b/README_CN.md index 553f6484f22eb98208e3af0478ca71e2fa4c8db3..ac643ca8098ccc9c28a4ca5a4da9b63a35484e19 100755 --- a/README_CN.md +++ b/README_CN.md @@ -5,7 +5,7 @@ # Release Note - 请查看最新版本0.1.64çš„release note ç¡®è®¤å˜æ›´ï¼Œ[0.1.64 release note](https://github.com/alibaba/flutter_boost/releases)。 + 请查看最新版本1.12.13+1çš„release note ç¡®è®¤å˜æ›´ï¼Œ[1.12.13+1 release note](https://github.com/alibaba/flutter_boost/releases)。 # FlutterBoost @@ -14,7 +14,7 @@ # å‰ç½®æ¡ä»¶ -在继ç»ä¹‹å‰ï¼Œæ‚¨éœ€è¦å°†Flutter集æˆåˆ°ä½ 现有的项目ä¸ã€‚flutter sdk çš„ç‰ˆæœ¬éœ€è¦ v1.9.1-hotfixes,å¦åˆ™ä¼šç¼–译失败. +在继ç»ä¹‹å‰ï¼Œæ‚¨éœ€è¦å°†Flutter集æˆåˆ°ä½ 现有的项目ä¸ã€‚flutter sdk 的版本需è¦å’Œboost版本适é…,å¦åˆ™ä¼šç¼–译失败. # FAQ è¯·é˜…è¯»è¿™ç¯‡æ–‡ç« : @@ -24,25 +24,17 @@ | Flutter Boost 版本 | 支æŒçš„ Flutter SDK 版本 | Description | æ˜¯å¦æ”¯æŒ AndroidX? | | ----------------------- | ----------------------- | ------------------------------------------------------------ | ------------------- | -| 0.1.50 | 1.5.4-hotfixes | android 如果其他 flutter 版本或者分支会编译错误。 | No | -| 0.1.51-0.1.59 | 1.5.4-hotfixes | 0.1.50 çš„ bugfix。 | No | -| 0.1.60 | 1.9.1-hotfixes | android 如果其他 flutter 分支会编译错误。 | No | -| 0.1.63 | 1.9.1-hotfixes | å’Œ 0.1.60 代ç åŒæ¥ï¼Œ bugfix 也会åˆå…¥è¯¥åˆ†æ”¯ï¼Œå¦‚果其他分支会编译错误。 | No | -| 0.1.61-0.1.69 | 1.9.1-hotfixes | 0.1.60 çš„ bugfix。 | No | | 1.9.1+2 | 1.9.1-hotfixes | 版本å·é‡æ–°å‘½å,开始默认支æŒandroidx | Yes | -| 1.12.13 | 1.12.13 -hotfixes | 支æŒandroidx | Yes | +| 1.12.13+1 | 1.12.13 -hotfixes | 支æŒandroidx | Yes | -| Flutter Boost 分支 | 支æŒçš„ Flutter SDK 版本 | Description | Support AndroidX? | +| Flutter Boost 分支 | 支æŒçš„ Flutter SDK 版本 | Description | æ˜¯å¦æ”¯æŒ AndroidX? | | --------------------- | --------------------------- | ------------------------------------------------------------ | ------------------ | | v1.9.1-hotfixes | 1.9.1-hotfixes | for androidx | Yes | -| task/task_v1.9.1_support_hotfixes| 1.9.1-hotfixes | for support | NO | | v1.12.13-hotfixes | 1.12.13-hotfixes | for androidx | Yes | -| task/task_v1.12.13_support_hotfixes| 1.12.13-hotfixes | for support | NO | - # 安装 @@ -56,15 +48,7 @@ androidx branch flutter_boost: git: url: 'https://github.com/alibaba/flutter_boost.git' - ref: '1.12.13' -``` -support branch -```json -flutter_boost: - git: - url: 'https://github.com/alibaba/flutter_boost.git' - ref: 'task/task_v1.12.13_support_hotfixes' - + ref: '1.12.13+1' ``` diff --git a/analysis_options.yaml b/analysis_options.yaml index 253401f317ca959d8284566ff950a5d464ce9ec9..9bd20edeebdf9c29c9099deee8b9fd4fbe83a2a9 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -20,6 +20,7 @@ analyzer: strong-mode: + implicit-casts: false implicit-dynamic: false errors: # treat missing required parameters as a warning (not a hint) @@ -38,9 +39,7 @@ analyzer: # see https://github.com/dart-lang/sdk/issues/28463 - "lib/i18n/messages_*.dart" - "lib/src/http/**" - - "example/**" - - "example_swift/**" - - "test/**" + linter: rules: # these rules are documented on and in the same order as @@ -60,6 +59,7 @@ linter: - avoid_classes_with_only_static_members # - avoid_double_and_int_checks # only useful when targeting JS runtime - avoid_empty_else + - avoid_equals_and_hash_code_on_mutable_classes - avoid_field_initializers_in_const_classes - avoid_function_literals_in_foreach_calls # - avoid_implementing_value_types # not yet tested @@ -67,7 +67,9 @@ linter: # - avoid_js_rounded_ints # only useful when targeting JS runtime - avoid_null_checks_in_equality_operators # - avoid_positional_boolean_parameters # not yet tested + # - avoid_print # not yet tested # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) + # - avoid_redundant_argument_values # not yet tested - avoid_relative_lib_imports - avoid_renaming_method_parameters - avoid_return_types_on_setters @@ -77,13 +79,16 @@ linter: # - avoid_returning_this # there are plenty of valid reasons to return this # - avoid_setters_without_getters # not yet tested # - avoid_shadowing_type_parameters # not yet tested - # - avoid_single_cascade_in_expression_statements # not yet tested + - avoid_single_cascade_in_expression_statements - avoid_slow_async_io - avoid_types_as_parameter_names # - avoid_types_on_closure_parameters # conflicts with always_specify_types + # - avoid_unnecessary_containers # not yet tested - avoid_unused_constructor_parameters - avoid_void_async + # - avoid_web_libraries_in_flutter # not yet tested - await_only_futures + - camel_case_extensions - camel_case_types - cancel_subscriptions # - cascade_invocations # not yet tested @@ -109,8 +114,11 @@ linter: # - lines_longer_than_80_chars # not yet tested - list_remove_unrelated_type # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 + # - missing_whitespace_between_adjacent_strings # not yet tested - no_adjacent_strings_in_list - no_duplicate_case_values + # - no_logic_in_create_state # not yet tested + # - no_runtimeType_toString # not yet tested - non_constant_identifier_names # - null_closures # not yet tested # - omit_local_variable_types # opposite of always_specify_types @@ -136,9 +144,9 @@ linter: - prefer_equal_for_default_values # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods - prefer_final_fields - # - prefer_final_in_for_each # not yet tested + - prefer_final_in_for_each - prefer_final_locals - # - prefer_for_elements_to_map_fromIterable # not yet tested + - prefer_for_elements_to_map_fromIterable - prefer_foreach # - prefer_function_declarations_over_variables # not yet tested - prefer_generic_function_type_aliases @@ -150,9 +158,11 @@ linter: # - prefer_interpolation_to_compose_strings # not yet tested - prefer_is_empty - prefer_is_not_empty + - prefer_is_not_operator - prefer_iterable_whereType # - prefer_mixin # https://github.com/dart-lang/language/issues/32 # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 + # - prefer_relative_imports # not yet tested - prefer_single_quotes - prefer_spread_collections - prefer_typing_uninitialized_variables @@ -173,6 +183,7 @@ linter: # - unnecessary_await_in_return # not yet tested - unnecessary_brace_in_string_interps - unnecessary_const + # - unnecessary_final # conflicts with prefer_final_locals - unnecessary_getters_setters # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 - unnecessary_new @@ -181,14 +192,16 @@ linter: - unnecessary_overrides - unnecessary_parenthesis - unnecessary_statements + # - unnecessary_string_interpolations - unnecessary_this - unrelated_type_equality_checks # - unsafe_html # not yet tested - use_full_hex_values_for_flutter_colors # - use_function_type_syntax_for_parameters # not yet tested + # - use_key_in_widget_constructors # not yet tested - use_rethrow_when_possible # - use_setters_to_change_properties # not yet tested # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review - valid_regexps - # - void_checks # not yet tested + - void_checks \ No newline at end of file diff --git a/android/src/main/java/com/idlefish/flutterboost/FlutterBoost.java b/android/src/main/java/com/idlefish/flutterboost/FlutterBoost.java index 2dd2dfaca9f2df88f8efd29253d28b2991a38594..82b8f6a0a336d1716c5fadb72072a4e1dba6be91 100644 --- a/android/src/main/java/com/idlefish/flutterboost/FlutterBoost.java +++ b/android/src/main/java/com/idlefish/flutterboost/FlutterBoost.java @@ -176,7 +176,7 @@ public class FlutterBoost { } DartExecutor.DartEntrypoint entrypoint = new DartExecutor.DartEntrypoint( FlutterMain.findAppBundlePath(), - "main" + mPlatform.dartEntrypoint() ); flutterEngine.getDartExecutor().executeDartEntrypoint(entrypoint); @@ -265,6 +265,9 @@ public class FlutterBoost { return ConfigBuilder.this.isDebug; } + @Override + public String dartEntrypoint() { return ConfigBuilder.this.dartEntrypoint; } + @Override public String initialRoute() { return ConfigBuilder.this.initialRoute; diff --git a/android/src/main/java/com/idlefish/flutterboost/Platform.java b/android/src/main/java/com/idlefish/flutterboost/Platform.java index 8e7faa507856c36dc5acf08a5cd4c9c8d1336a3d..e5f222155718ca827afb27bc6ac4f58e7b8b03ad 100644 --- a/android/src/main/java/com/idlefish/flutterboost/Platform.java +++ b/android/src/main/java/com/idlefish/flutterboost/Platform.java @@ -38,6 +38,8 @@ public abstract class Platform { public abstract boolean isDebug(); + public abstract String dartEntrypoint(); + public abstract String initialRoute(); public FlutterBoost.BoostLifecycleListener lifecycleListener; diff --git a/example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/MyApplication.java b/example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/MyApplication.java index d2e243e74a5720d38d2ac33a4f806084869fb196..7d1561b52c8f29f2657906beb5c5b23375ec7d9e 100755 --- a/example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/MyApplication.java +++ b/example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/MyApplication.java @@ -3,9 +3,11 @@ package com.taobao.idlefish.flutterboostexample; import android.app.Application; import android.content.Context; +import android.os.Build; import android.util.Log; import com.idlefish.flutterboost.*; +import java.util.HashMap; import java.util.Map; import com.idlefish.flutterboost.interfaces.INativeRouter; @@ -13,7 +15,7 @@ import io.flutter.embedding.android.FlutterView; import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.PluginRegistry; -import io.flutter.plugins.GeneratedPluginRegistrant; +import io.flutter.plugin.common.StandardMessageCodec; public class MyApplication extends Application { @@ -41,6 +43,26 @@ public class MyApplication extends Application { @Override public void onEngineCreated() { + // 注册MethodChannel,监å¬flutterä¾§çš„getPlatformVersion调用 + MethodChannel methodChannel = new MethodChannel(FlutterBoost.instance().engineProvider().getDartExecutor(), "flutter_native_channel"); + methodChannel.setMethodCallHandler((call, result) -> { + + if (call.method.equals("getPlatformVersion")) { + result.success(Build.VERSION.RELEASE); + } else { + result.notImplemented(); + } + + }); + + // 注册PlatformView viewTypeIdè¦å’Œflutterä¸çš„viewType对应 + FlutterBoost + .instance() + .engineProvider() + .getPlatformViewsController() + .getRegistry() + .registerViewFactory("plugins.test/view", new TextPlatformViewFactory(StandardMessageCodec.INSTANCE)); + } @Override diff --git a/example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/TextPlatformViewPlugin.java b/example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/TextPlatformViewPlugin.java deleted file mode 100644 index 95e0d77a0f49abcaf812e1742d33792cf481c71a..0000000000000000000000000000000000000000 --- a/example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/TextPlatformViewPlugin.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.taobao.idlefish.flutterboostexample; - -import io.flutter.app.FlutterPluginRegistry; -import io.flutter.plugin.common.PluginRegistry; -import io.flutter.plugin.common.StandardMessageCodec; - -public class TextPlatformViewPlugin { - public static void register(PluginRegistry.Registrar registrar) { - registrar.platformViewRegistry().registerViewFactory("plugins.test/view", - new TextPlatformViewFactory(StandardMessageCodec.INSTANCE)); - } -} diff --git a/example/ios/Runner/AppDelegate.m b/example/ios/Runner/AppDelegate.m index 5861f9bc5bfd569da8e20b101233ee587c21e1be..f851ae5dacc6cadf7776d30d7d5522039f8724d5 100755 --- a/example/ios/Runner/AppDelegate.m +++ b/example/ios/Runner/AppDelegate.m @@ -23,8 +23,22 @@ PlatformRouterImp *router = [PlatformRouterImp new]; [FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router onStart:^(FlutterEngine *engine) { - - }]; + + // 注册MethodChannel,监å¬flutterä¾§çš„getPlatformVersion调用 + FlutterMethodChannel *flutterMethodChannel = [FlutterMethodChannel methodChannelWithName:@"flutter_native_channel" binaryMessenger:engine.binaryMessenger]; + + [flutterMethodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) { + + NSString *method = call.method; + if ([method isEqualToString:@"getPlatformVersion"]) { + NSString *sysVersion = [[UIDevice currentDevice] systemVersion]; + result(sysVersion); + } else { + result(FlutterMethodNotImplemented); + } + + }]; + }]; self.window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds]; diff --git a/example/lib/main.dart b/example/lib/main.dart index 23a586212d9a2a500a21b048d428b090044e4974..a15f6528039b8e82c4026f4172ab7050c8d584fa 100755 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -16,20 +16,26 @@ class _MyAppState extends State<MyApp> { void initState() { super.initState(); - FlutterBoost.singleton.registerPageBuilders({ - 'embeded': (pageName, params, _)=>EmbededFirstRouteWidget(), - 'first': (pageName, params, _) => FirstRouteWidget(), - 'firstFirst': (pageName, params, _) => FirstFirstRouteWidget(), - 'second': (pageName, params, _) => SecondRouteWidget(), - 'secondStateful': (pageName, params, _) => SecondStatefulRouteWidget(), - 'tab': (pageName, params, _) => TabRouteWidget(), - 'platformView': (pageName, params, _) => PlatformRouteWidget(), - 'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params), + FlutterBoost.singleton.registerPageBuilders(<String, PageBuilder>{ + 'embeded': (String pageName, Map<String, dynamic> params, String _) => + EmbeddedFirstRouteWidget(), + 'first': (String pageName, Map<String, dynamic> params, String _) => FirstRouteWidget(), + 'firstFirst': (String pageName, Map<String, dynamic> params, String _) => + FirstFirstRouteWidget(), + 'second': (String pageName, Map<String, dynamic> params, String _) => SecondRouteWidget(), + 'secondStateful': (String pageName, Map<String, dynamic> params, String _) => + SecondStatefulRouteWidget(), + 'tab': (String pageName, Map<String, dynamic> params, String _) => TabRouteWidget(), + 'platformView': (String pageName, Map<String, dynamic> params, String _) => + PlatformRouteWidget(), + 'flutterFragment': (String pageName, Map<String, dynamic> params, String _) => + FragmentRouteWidget(params), + ///å¯ä»¥åœ¨native层通过 getContainerParams æ¥ä¼ 递傿•° - 'flutterPage': (pageName, params, _) { - print("flutterPage params:$params"); + 'flutterPage': (String pageName, Map<String, dynamic> params, String _) { + print('flutterPage params:$params'); - return FlutterRouteWidget(params:params); + return FlutterRouteWidget(params: params); }, }); FlutterBoost.singleton.addBoostNavigatorObserver(TestBoostNavigatorObserver()); @@ -40,31 +46,36 @@ class _MyAppState extends State<MyApp> { return MaterialApp( title: 'Flutter Boost example', builder: FlutterBoost.init(postPush: _onRoutePushed), - home: Container( - color:Colors.white - )); + home: Container(color: Colors.white)); } void _onRoutePushed( - String pageName, String uniqueId, Map params, Route route, Future _) { - } + String pageName, + String uniqueId, + Map<String, dynamic> params, + Route<dynamic> route, + Future<dynamic> _, + ) {} } -class TestBoostNavigatorObserver extends NavigatorObserver{ - void didPush(Route<dynamic> route, Route<dynamic> previousRoute) { - print("flutterboost#didPush"); +class TestBoostNavigatorObserver extends NavigatorObserver { + @override + void didPush(Route<dynamic> route, Route<dynamic> previousRoute) { + print('flutterboost#didPush'); } + @override void didPop(Route<dynamic> route, Route<dynamic> previousRoute) { - print("flutterboost#didPop"); + print('flutterboost#didPop'); } + @override void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) { - print("flutterboost#didRemove"); + print('flutterboost#didRemove'); } + @override void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) { - print("flutterboost#didReplace"); + print('flutterboost#didReplace'); } } - diff --git a/example/lib/platform_view.dart b/example/lib/platform_view.dart index 26d5b91670600d51310cdd8650a7f6ecd8d228cd..139444d6df4749923d4e7347d339e788821c6e61 100644 --- a/example/lib/platform_view.dart +++ b/example/lib/platform_view.dart @@ -3,7 +3,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -typedef void TextViewCreatedCallback(TextViewController controller); +typedef TextViewCreatedCallback = void Function(TextViewController controller); class TextView extends StatefulWidget { const TextView({ @@ -34,13 +34,13 @@ class _TextViewState extends State<TextView> { if (widget.onTextViewCreated == null) { return; } - widget.onTextViewCreated(new TextViewController._(id)); + widget.onTextViewCreated(TextViewController._(id)); } } class TextViewController { TextViewController._(int id) - : _channel = new MethodChannel('plugins.felix.angelov/textview_$id'); + : _channel = MethodChannel('plugins.felix.angelov/textview_$id'); final MethodChannel _channel; @@ -48,4 +48,4 @@ class TextViewController { assert(text != null); return _channel.invokeMethod('setText', text); } -} \ No newline at end of file +} diff --git a/example/lib/simple_page_widgets.dart b/example/lib/simple_page_widgets.dart index b5e9fc06c4e5a4b347b95a76b9c4c3cc050e7ce3..7822b425d2dd11fdf78bc0515dc917bcc7fa1c09 100644 --- a/example/lib/simple_page_widgets.dart +++ b/example/lib/simple_page_widgets.dart @@ -1,17 +1,35 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_boost/flutter_boost.dart'; import 'package:flutter_boost_example/platform_view.dart'; class FirstRouteWidget extends StatefulWidget { @override - State<StatefulWidget> createState() { - return new _FirstRouteWidgetState(); - } + State<StatefulWidget> createState() => _FirstRouteWidgetState(); } -class _FirstRouteWidgetState extends State<FirstRouteWidget>{ + +class _FirstRouteWidgetState extends State<FirstRouteWidget> { _FirstRouteWidgetState(); + // flutter ä¾§MethodChannelé…置,channel name需è¦å’Œnative侧一致 + static const MethodChannel _methodChannel = MethodChannel('flutter_native_channel'); + String _systemVersion = ''; + + Future<dynamic> _getPlatformVersion() async { + + try { + final String result = await _methodChannel.invokeMethod('getPlatformVersion'); + print('getPlatformVersion:' + result); + setState(() { + _systemVersion = result; + }); + } on PlatformException catch (e) { + print(e.message); + } + + } + @override void initState() { print('initState'); @@ -45,80 +63,90 @@ class _FirstRouteWidgetState extends State<FirstRouteWidget>{ @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text('First Route'), - ), + appBar: AppBar(title: const Text('First Route')), body: Center( - child: - Column( + child: Column( mainAxisAlignment: MainAxisAlignment.center, - children: - <Widget>[ + children: <Widget>[ RaisedButton( - child: Text('Open native page'), - onPressed: () { - print("open natve page!"); - FlutterBoost.singleton.open("native").then((Map value) { - print( - "call me when page is finished. did recieve native route result $value"); - }); - }, - ), - RaisedButton( - child: Text('Open FF route'), - onPressed: () { - print("open FF page!"); - FlutterBoost.singleton.open("firstFirst").then((Map value) { - print( - "call me when page is finished. did recieve FF route result $value"); - }); - }, - ), - RaisedButton( - child: Text('Open second route1'), - 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"); - }); - }, - ), - - RaisedButton( - child: Text('Present second stateful route'), - onPressed: () { - print("Present second stateful page!"); - FlutterBoost.singleton.open("secondStateful",urlParams:<dynamic,dynamic>{"present":true}).then((Map value) { - print( - "call me when page is finished. did recieve second stateful route result $value"); - }); - }, - ), - RaisedButton( - child: Text('Present second route'), - onPressed: () { - print("Present second page!"); - FlutterBoost.singleton.open("second",urlParams:<dynamic,dynamic>{"present":true}).then((Map value) { - print( - "call me when page is finished. did recieve second route result $value"); - }); - }, - ), - ], + child: const Text('Open native page'), + onPressed: () { + print('open natve page!'); + FlutterBoost.singleton + .open('native') + .then((Map<dynamic, dynamic> value) { + print( + 'call me when page is finished. did recieve native route result $value'); + }); + }, + ), + RaisedButton( + child: const Text('Open FF route'), + onPressed: () { + print('open FF page!'); + FlutterBoost.singleton + .open('firstFirst') + .then((Map<dynamic, dynamic> value) { + print( + 'call me when page is finished. did recieve FF route result $value'); + }); + }, + ), + RaisedButton( + child: const Text('Open second route1'), + onPressed: () { + print('open second page!'); + FlutterBoost.singleton + .open('second') + .then((Map<dynamic, dynamic> value) { + print( + 'call me when page is finished. did recieve second route result $value'); + }); + }, + ), + RaisedButton( + child: const Text('Present second stateful route'), + onPressed: () { + print('Present second stateful page!'); + FlutterBoost.singleton.open('secondStateful', + urlParams: <String, dynamic>{ + 'present': true + }).then((Map<dynamic, dynamic> value) { + print( + 'call me when page is finished. did recieve second stateful route result $value'); + }); + }, + ), + RaisedButton( + child: const Text('Present second route'), + onPressed: () { + print('Present second page!'); + FlutterBoost.singleton.open('second', + urlParams: <String, dynamic>{ + 'present': true + }).then((Map<dynamic, dynamic> value) { + print( + 'call me when page is finished. did recieve second route result $value'); + }); + }, + ), + RaisedButton( + child: Text('Get system version by method channel:' + _systemVersion), + onPressed: () => _getPlatformVersion(), + ), + ], ), ), ); } } + class FirstFirstRouteWidget extends StatefulWidget { @override - State<StatefulWidget> createState() { - return new _FirstFirstRouteWidgetState(); - } + State<StatefulWidget> createState() => _FirstFirstRouteWidgetState(); } -class _FirstFirstRouteWidgetState extends State<FirstFirstRouteWidget>{ +class _FirstFirstRouteWidgetState extends State<FirstFirstRouteWidget> { _FirstFirstRouteWidgetState(); @override @@ -154,20 +182,18 @@ class _FirstFirstRouteWidgetState extends State<FirstFirstRouteWidget>{ @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text('First Route'), - ), + appBar: AppBar(title: const Text('First Route')), body: Center( child: RaisedButton( - child: Text('Open first route'), + child: const Text('Open first route'), onPressed: () { - - print("open first page again!"); - FlutterBoost.singleton.open("first").then((Map value){ - print("did recieve first route result"); - print("did recieve first route result $value"); + print('open first page again!'); + FlutterBoost.singleton + .open('first') + .then((Map<dynamic, dynamic> value) { + print('did recieve first route result'); + print('did recieve first route result $value'); }); - }, ), ), @@ -175,34 +201,33 @@ class _FirstFirstRouteWidgetState extends State<FirstFirstRouteWidget>{ } } -class EmbededFirstRouteWidget extends StatefulWidget { +class EmbeddedFirstRouteWidget extends StatefulWidget { @override - State<StatefulWidget> createState() { - // TODO: implement createState - return _EmbededFirstRouteWidgetState(); - } - + State<StatefulWidget> createState() => _EmbeddedFirstRouteWidgetState(); } -class _EmbededFirstRouteWidgetState extends State<EmbededFirstRouteWidget> { +class _EmbeddedFirstRouteWidgetState extends State<EmbeddedFirstRouteWidget> { @override Widget build(BuildContext context) { print('_EmbededFirstRouteWidgetState build called!'); return Scaffold( body: Center( child: RaisedButton( - child: Text('Open second route2'), + child: const Text('Open second route2'), onPressed: () { - print("open second page!"); - FlutterBoost.singleton.open("second").then((Map value) { + print('open second page!'); + FlutterBoost.singleton + .open('second') + .then((Map<dynamic, dynamic> value) { print( - "call me when page is finished. did recieve second route result $value"); + 'call me when page is finished. did recieve second route result $value'); }); }, ), ), ); } + @override void dispose() { print('[XDEBUG]:_EmbededFirstRouteWidgetState disposing~'); @@ -212,29 +237,24 @@ class _EmbededFirstRouteWidgetState extends State<EmbededFirstRouteWidget> { class SecondStatefulRouteWidget extends StatefulWidget { @override - State<StatefulWidget> createState() { - // TODO: implement createState - return _SecondStatefulRouteWidgetState(); - } + State<StatefulWidget> createState() => _SecondStatefulRouteWidgetState(); } -class _SecondStatefulRouteWidgetState extends State<SecondStatefulRouteWidget>{ + +class _SecondStatefulRouteWidgetState extends State<SecondStatefulRouteWidget> { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text("SecondStateful Route"), - ), + appBar: AppBar(title: const Text('SecondStateful Route')), body: Center( child: RaisedButton( onPressed: () { // Navigate back to first route when tapped. - - BoostContainerSettings settings = + final BoostContainerSettings settings = BoostContainer.of(context).settings; FlutterBoost.singleton.close(settings.uniqueId, - result: <dynamic,dynamic>{"result": "data from second"}); + result: <String, dynamic>{'result': 'data from second'}); }, - child: Text('Go back with result!'), + child: const Text('Go back with result!'), ), ), ); @@ -251,20 +271,19 @@ class SecondRouteWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text("Second Route"), - ), + appBar: AppBar(title: const Text('Second Route')), body: Center( child: RaisedButton( onPressed: () { // Navigate back to first route when tapped. - - BoostContainerSettings settings = + final BoostContainerSettings settings = BoostContainer.of(context).settings; - FlutterBoost.singleton.close(settings.uniqueId, - result: <dynamic,dynamic>{"result": "data from second"}); + FlutterBoost.singleton.close( + settings.uniqueId, + result: <String, dynamic>{'result': 'data from second'}, + ); }, - child: Text('Go back with result!'), + child: const Text('Go back with result!'), ), ), ); @@ -275,15 +294,13 @@ class TabRouteWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text("Tab Route"), - ), + appBar: AppBar(title: const Text('Tab Route')), body: Center( child: RaisedButton( onPressed: () { - FlutterBoost.singleton.open("second"); + FlutterBoost.singleton.open('second'); }, - child: Text('Open second route3'), + child: const Text('Open second route3'), ), ), ); @@ -294,17 +311,17 @@ class PlatformRouteWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title:Text("Platform Route"), - ), + appBar: AppBar(title: const Text('Platform Route')), body: Center( child: RaisedButton( - child: TextView(), + child: const TextView(), onPressed: () { - print("open second page!"); - FlutterBoost.singleton.open("second").then((Map value) { + print('open second page!'); + FlutterBoost.singleton + .open('second') + .then((Map<dynamic, dynamic> value) { print( - "call me when page is finished. did recieve second route result $value"); + 'call me when page is finished. did recieve second route result $value'); }); }, ), @@ -312,9 +329,11 @@ class PlatformRouteWidget extends StatelessWidget { ); } } + class FlutterRouteWidget extends StatefulWidget { - FlutterRouteWidget({this.params,this.message}); - final Map params; + const FlutterRouteWidget({this.params, this.message}); + + final Map<String, dynamic> params; final String message; @override @@ -322,190 +341,229 @@ class FlutterRouteWidget extends StatefulWidget { } class _FlutterRouteWidgetState extends State<FlutterRouteWidget> { - final TextEditingController _usernameController = TextEditingController(); + + // flutter ä¾§MethodChannelé…置,channel name需è¦å’Œnative侧一致 + static const MethodChannel _methodChannel = MethodChannel('flutter_native_channel'); + String _systemVersion = ''; + + Future<dynamic> _getPlatformVersion() async { + + try { + final String result = await _methodChannel.invokeMethod('getPlatformVersion'); + print('getPlatformVersion:' + result); + setState(() { + _systemVersion = result; + }); + } on PlatformException catch (e) { + print(e.message); + } + + } @override Widget build(BuildContext context) { - final String message=widget.message; + final String message = widget.message; return Scaffold( appBar: AppBar( - brightness:Brightness.light, + brightness: Brightness.light, backgroundColor: Colors.white, - textTheme:new TextTheme(title: TextStyle(color: Colors.black)) , - - title: Text('flutter_boost_example'), + textTheme: const TextTheme(title: TextStyle(color: Colors.black)), + title: const Text('flutter_boost_example'), ), body: SingleChildScrollView( - child:Container( - margin: const EdgeInsets.all(24.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: <Widget>[ - Container( - margin: const EdgeInsets.only(top: 10.0,bottom: 20.0), - child: Text( - message ?? "This is a flutter activity \n params:${widget.params}", - style: TextStyle(fontSize: 28.0, color: Colors.blue), + child: Container( + margin: const EdgeInsets.all(24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: <Widget>[ + Container( + margin: const EdgeInsets.only(top: 10.0, bottom: 20.0), + child: Text( + message ?? + 'This is a flutter activity \n params:${widget.params}', + style: TextStyle(fontSize: 28.0, color: Colors.blue), + ), + alignment: AlignmentDirectional.center, + ), + const CupertinoTextField( + prefix: Icon( + CupertinoIcons.person_solid, + color: CupertinoColors.lightBackgroundGray, + size: 28.0, + ), + padding: EdgeInsets.symmetric(horizontal: 6.0, vertical: 12.0), + clearButtonMode: OverlayVisibilityMode.editing, + textCapitalization: TextCapitalization.words, + autocorrect: false, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + width: 0.0, color: CupertinoColors.inactiveGray), ), - alignment: AlignmentDirectional.center, ), -// Expanded(child: Container()), - const CupertinoTextField( - prefix: Icon( - CupertinoIcons.person_solid, - color: CupertinoColors.lightBackgroundGray, - size: 28.0, - ), - padding: EdgeInsets.symmetric(horizontal: 6.0, vertical: 12.0), - clearButtonMode: OverlayVisibilityMode.editing, - textCapitalization: TextCapitalization.words, - ), - new TextField( - enabled: true, - autocorrect: true, - style: const TextStyle( - fontSize: 20.0, - color: const Color(0xFF222222), - fontWeight: FontWeight.w500), - ), new TextField( - controller: new TextEditingController(), - focusNode:FocusNode(), - enabled: true, - autocorrect: false, - style: const TextStyle( - fontSize: 20.0, - color: const Color(0xFF222222), - fontWeight: FontWeight.w500), + placeholder: 'Name', + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: const Text( + 'open native page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open native page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - - ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 - ///例如:sample://nativePage?aaa=bbb - onTap: () => FlutterBoost.singleton - .open("sample://nativePage", urlParams: <dynamic,dynamic>{ - "query": {"aaa": "bbb"} - }), + + /// åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 + /// 例如:sample://nativePage?aaa=bbb + onTap: () => FlutterBoost.singleton.open( + 'sample://nativePage', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'} + }, ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open first', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - - ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 - ///例如:sample://nativePage?aaa=bbb - onTap: () => FlutterBoost.singleton - .open("first", urlParams: <dynamic,dynamic>{ - "query": {"aaa": "bbb"} - }), + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: const Text( + 'open first', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), + + /// åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 + /// 例如:sample://nativePage?aaa=bbb + onTap: () => FlutterBoost.singleton.open( + 'first', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'} + }, ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open second', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - - ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 - ///例如:sample://nativePage?aaa=bbb - onTap: () => FlutterBoost.singleton - .open("second", urlParams:<dynamic,dynamic> { - "query": {"aaa": "bbb"} - }), + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: const Text( + 'open second', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open tab', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - - ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 - ///例如:sample://nativePage?aaa=bbb - onTap: () => FlutterBoost.singleton - .open("tab", urlParams:<dynamic,dynamic> { - "query": {"aaa": "bbb"} - }), + + /// åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 + /// 例如:sample://nativePage?aaa=bbb + onTap: () => FlutterBoost.singleton.open( + 'second', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'} + }, ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open flutter page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - - ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 - ///例如:sample://nativePage?aaa=bbb - onTap: () => FlutterBoost.singleton - .open("sample://flutterPage", urlParams:<String,dynamic> { - "query": {"aaa": "bbb"} - }), + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: const Text( + 'open tab', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'push flutter widget', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - onTap: () { - Navigator.push<dynamic>(context, - MaterialPageRoute<dynamic>(builder: (_) => PushWidget())); + + /// åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 + /// 例如:sample://nativePage?aaa=bbb + onTap: () => FlutterBoost.singleton.open( + 'tab', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'} }, ), + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: const Text( + 'open flutter page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), + /// åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 + /// 例如:sample://nativePage?aaa=bbb + onTap: () => FlutterBoost.singleton.open( + 'sample://flutterPage', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'} + }, + ), + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: const Text( + 'push flutter widget', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), + onTap: () { + Navigator.push<dynamic>( + context, + MaterialPageRoute<dynamic>(builder: (_) => PushWidget()), + ); + }, + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: const Text( + 'push Platform demo', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), + onTap: () { + Navigator.push<dynamic>( + context, + MaterialPageRoute<dynamic>( + builder: (_) => PlatformRouteWidget()), + ); + }, + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: const Text( + 'open flutter fragment page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), + onTap: () => + FlutterBoost.singleton.open('sample://flutterFragmentPage'), + ), InkWell( child: Container( padding: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0), color: Colors.yellow, child: Text( - 'push Platform demo', + 'get system version by method channel:' + _systemVersion, style: TextStyle(fontSize: 22.0, color: Colors.black), )), - onTap: () { - Navigator.push<dynamic>(context, - MaterialPageRoute<dynamic>(builder: (_) => PlatformRouteWidget())); - }, + onTap: () => _getPlatformVersion(), ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open flutter fragment page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - onTap: () => FlutterBoost.singleton - .open("sample://flutterFragmentPage"), - ), - ], - ), - + ], + ), ), ), ); @@ -513,23 +571,21 @@ class _FlutterRouteWidgetState extends State<FlutterRouteWidget> { } class FragmentRouteWidget extends StatelessWidget { - final Map params; + const FragmentRouteWidget(this.params); - FragmentRouteWidget(this.params); + final Map<String, dynamic> params; @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text('flutter_boost_example'), - ), + appBar: AppBar(title: const Text('flutter_boost_example')), body: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Container( margin: const EdgeInsets.only(top: 80.0), child: Text( - "This is a flutter fragment", + 'This is a flutter fragment', style: TextStyle(fontSize: 28.0, color: Colors.blue), ), alignment: AlignmentDirectional.center, @@ -537,7 +593,7 @@ class FragmentRouteWidget extends StatelessWidget { Container( margin: const EdgeInsets.only(top: 32.0), child: Text( - params['tag'] ?? '', + '${params['tag']}' ?? '', style: TextStyle(fontSize: 28.0, color: Colors.red), ), alignment: AlignmentDirectional.center, @@ -545,37 +601,40 @@ class FragmentRouteWidget extends StatelessWidget { Expanded(child: Container()), InkWell( child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open native page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - onTap: () => FlutterBoost.singleton.open("sample://nativePage"), + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: const Text( + 'open native page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), + onTap: () => FlutterBoost.singleton.open('sample://nativePage'), ), InkWell( child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open flutter page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - onTap: () => FlutterBoost.singleton.open("sample://flutterPage"), + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: const Text( + 'open flutter page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), + onTap: () => FlutterBoost.singleton.open('sample://flutterPage'), ), InkWell( child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 80.0), - color: Colors.yellow, - child: Text( - 'open flutter fragment page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 80.0), + color: Colors.yellow, + child: const Text( + 'open flutter fragment page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), onTap: () => - FlutterBoost.singleton.open("sample://flutterFragmentPage"), + FlutterBoost.singleton.open('sample://flutterFragmentPage'), ) ], ), @@ -591,15 +650,8 @@ class PushWidget extends StatefulWidget { class _PushWidgetState extends State<PushWidget> { VoidCallback _backPressedListenerUnsub; - @override - void initState() { - // TODO: implement initState - super.initState(); - } - @override void didChangeDependencies() { - // TODO: implement didChangeDependencies super.didChangeDependencies(); // if (_backPressedListenerUnsub == null) { @@ -615,7 +667,6 @@ class _PushWidgetState extends State<PushWidget> { @override void dispose() { - // TODO: implement dispose print('[XDEBUG] - PushWidget is disposing~'); super.dispose(); _backPressedListenerUnsub?.call(); @@ -623,6 +674,6 @@ class _PushWidgetState extends State<PushWidget> { @override Widget build(BuildContext context) { - return FlutterRouteWidget(message: "Pushed Widget"); + return const FlutterRouteWidget(message: 'Pushed Widget'); } } diff --git a/example/lib/test_input.dart b/example/lib/test_input.dart index dbb8d3148d2de8709e96fd233651de31b924fc94..c5d345dd3d669a8c7cff3556bbaf66378e6e36ed 100644 --- a/example/lib/test_input.dart +++ b/example/lib/test_input.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; class TestPage extends StatefulWidget { - TestPage({Key key, this.title = "Input Test"}) : super(key: key); + const TestPage({ + Key key, + this.title = 'Input Test', + }) : super(key: key); final String title; @@ -18,95 +21,82 @@ class _TestPageState extends State<TestPage> { }); } - @override - void initState() { - // TODO: implement initState - super.initState(); - } - @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), + appBar: AppBar(title: Text(widget.title)), body: SafeArea( - bottom: false, - child: ListView( - children: <Widget>[ - Container( - child: Text( - 'You have pushed the button this many times:', + bottom: false, + child: ListView( + children: <Widget>[ + Container( + child: const Text( + 'You have pushed the button this many times:', + ), + margin: const EdgeInsets.all(8.0), + alignment: Alignment.center, ), - margin: const EdgeInsets.all(8.0), - alignment: Alignment.center, - ), - Container( - child: Text( - '$_counter', - style: Theme.of(context).textTheme.display1, + Container( + child: Text( + '$_counter', + style: Theme.of(context).textTheme.display1, + ), + margin: const EdgeInsets.all(8.0), + alignment: Alignment.center, ), - margin: const EdgeInsets.all(8.0), - alignment: Alignment.center, - ), - Container( - child: TextField( - minLines: 2, - maxLines: 10, + Container( + child: const TextField(minLines: 2, maxLines: 10), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - TestTextField(), - Container( - child: Container( - color: Colors.red, - width: double.infinity, - height: 128.0, + TestTextField(), + Container( + child: Container( + color: Colors.red, + width: double.infinity, + height: 128.0, + ), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - Container( - child: Container( - color: Colors.orange, - width: double.infinity, - height: 128.0, + Container( + child: Container( + color: Colors.orange, + width: double.infinity, + height: 128.0, + ), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - Container( - child: Container( - color: Colors.green, - width: double.infinity, - height: 128.0, + Container( + child: Container( + color: Colors.green, + width: double.infinity, + height: 128.0, + ), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - Container( - child: Container( - color: Colors.blue, - width: double.infinity, - height: 128.0, + Container( + child: Container( + color: Colors.blue, + width: double.infinity, + height: 128.0, + ), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - Container( - child: Container( - color: Colors.yellow, - width: double.infinity, - height: 128.0, + Container( + child: Container( + color: Colors.yellow, + width: double.infinity, + height: 128.0, + ), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - Container( - child: TextField( - minLines: 2, - maxLines: 10, + Container( + child: const TextField(minLines: 2, maxLines: 10), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - TestTextField(), - ], - )), + TestTextField(), + ], + ), + ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', @@ -123,22 +113,22 @@ class TestTextField extends StatefulWidget { class _TestTextFieldState extends State<TestTextField> { FocusNode _node; - PersistentBottomSheetController _controller; + PersistentBottomSheetController<dynamic> _controller; @override void initState() { - // TODO: implement initState super.initState(); _node = FocusNode(); _node.addListener(() { if (_node.hasFocus) { print('showBottomSheet'); - _controller = Scaffold.of(context) - .showBottomSheet<dynamic>((BuildContext ctx) => Container( - width: double.infinity, - height: 36.0, - color: Colors.deepPurple, - )); + _controller = Scaffold.of(context).showBottomSheet<dynamic>( + (BuildContext ctx) => Container( + width: double.infinity, + height: 36.0, + color: Colors.deepPurple, + ), + ); } else { if (_controller != null) { //Navigator.of(context).pop(); diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index f0f1b81d5c15014e5048d17de494d97d91f3d34f..e1d0651904f5ccefeb4fb035325ef5338fad0560 100755 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -6,13 +6,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; - -import '../lib/main.dart'; +import 'package:flutter_boost_example/main.dart'; void main() { testWidgets('Verify Platform version', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(new MyApp()); + await tester.pumpWidget(MyApp()); // Verify that platform version is retrieved. expect( diff --git a/example_swift/lib/main.dart b/example_swift/lib/main.dart index 8290d30407419d2dd764ff1deccc5a070d757dbf..8e30e39072506a1e2501642aa4453fd0f9352966 100755 --- a/example_swift/lib/main.dart +++ b/example_swift/lib/main.dart @@ -16,17 +16,22 @@ class _MyAppState extends State<MyApp> { void initState() { super.initState(); - FlutterBoost.singleton.registerPageBuilders({ - 'first': (pageName, params, _) => FirstRouteWidget(), - 'second': (pageName, params, _) => SecondRouteWidget(), - 'tab': (pageName, params, _) => TabRouteWidget(), - 'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params), + FlutterBoost.singleton.registerPageBuilders(<String, PageBuilder>{ + 'first': (String pageName, Map<String, dynamic> params, String _) => + FirstRouteWidget(), + 'second': (String pageName, Map<String, dynamic> params, String _) => + SecondRouteWidget(), + 'tab': (String pageName, Map<String, dynamic> params, String _) => + TabRouteWidget(), + 'flutterFragment': + (String pageName, Map<String, dynamic> params, String _) => + FragmentRouteWidget(params), ///å¯ä»¥åœ¨native层通过 getContainerParams æ¥ä¼ 递傿•° - 'flutterPage': (pageName, params, _) { - print("flutterPage params:$params"); + 'flutterPage': (String pageName, Map<String, dynamic> params, String _) { + print('flutterPage params:$params'); - return FlutterRouteWidget(); + return const FlutterRouteWidget(); }, }); } @@ -34,12 +39,17 @@ class _MyAppState extends State<MyApp> { @override Widget build(BuildContext context) { return MaterialApp( - title: 'Flutter Boost example', - builder: FlutterBoost.init(postPush: _onRoutePushed), - home: Container()); + title: 'Flutter Boost example', + builder: FlutterBoost.init(postPush: _onRoutePushed), + home: Container(), + ); } void _onRoutePushed( - String pageName, String uniqueId, Map params, Route route, Future _) { - } + String pageName, + String uniqueId, + Map<String, dynamic> params, + Route<dynamic> route, + Future<dynamic> _, + ) {} } diff --git a/example_swift/lib/simple_page_widgets.dart b/example_swift/lib/simple_page_widgets.dart index 67d5c87800355e2ee408858ddcb210b7763d8059..854acaca4f05232659a9f9e0caaec76748f9a14d 100755 --- a/example_swift/lib/simple_page_widgets.dart +++ b/example_swift/lib/simple_page_widgets.dart @@ -6,15 +6,18 @@ class FirstRouteWidget extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('First Route'), + title: const Text('First Route'), ), body: Center( child: RaisedButton( - child: Text('Open second route'), + child: const 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"); + print('open second page!'); + FlutterBoost.singleton + .open('second') + .then((Map<dynamic, dynamic> value) { + print( + 'call me when page is finished. did recieve second route result $value'); }); }, ), @@ -28,19 +31,21 @@ class SecondRouteWidget extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text("Second Route"), + title: const Text('Second Route'), ), body: Center( child: RaisedButton( onPressed: () { // Navigate back to first route when tapped. - BoostContainerSettings settings = + final BoostContainerSettings settings = BoostContainer.of(context).settings; - FlutterBoost.singleton.close(settings.uniqueId, - result: <dynamic,dynamic>{"result": "data from second"}); + FlutterBoost.singleton.close( + settings.uniqueId, + result: <String, dynamic>{'result': 'data from second'}, + ); }, - child: Text('Go back with result!'), + child: const Text('Go back with result!'), ), ), ); @@ -51,15 +56,13 @@ class TabRouteWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text("Tab Route"), - ), + appBar: AppBar(title: const Text('Tab Route')), body: Center( child: RaisedButton( onPressed: () { - FlutterBoost.singleton.open("second"); + FlutterBoost.singleton.open('second'); }, - child: Text('Open second route'), + child: const Text('Open second route'), ), ), ); @@ -67,15 +70,15 @@ class TabRouteWidget extends StatelessWidget { } class FlutterRouteWidget extends StatelessWidget { - final String message; + const FlutterRouteWidget({this.message}); - FlutterRouteWidget({this.message}); + final String message; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('flutter_boost_example'), + title: const Text('flutter_boost_example'), ), body: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -83,7 +86,7 @@ class FlutterRouteWidget extends StatelessWidget { Container( margin: const EdgeInsets.only(top: 80.0), child: Text( - message ?? "This is a flutter activity", + message ?? 'This is a flutter activity', style: TextStyle(fontSize: 28.0, color: Colors.blue), ), alignment: AlignmentDirectional.center, @@ -101,10 +104,12 @@ class FlutterRouteWidget extends StatelessWidget { ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 ///例如:sample://nativePage?aaa=bbb - onTap: () => - FlutterBoost.singleton.open("sample://nativePage", urlParams: <dynamic,dynamic>{ - "query": {"aaa": "bbb"} - }), + onTap: () => FlutterBoost.singleton.open( + 'sample://nativePage', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'} + }, + ), ), InkWell( child: Container( @@ -118,36 +123,42 @@ class FlutterRouteWidget extends StatelessWidget { ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 ///例如:sample://nativePage?aaa=bbb - onTap: () => - FlutterBoost.singleton.open("sample://flutterPage", urlParams: <dynamic,dynamic>{ - "query": {"aaa": "bbb"} - }), + onTap: () => FlutterBoost.singleton.open( + 'sample://flutterPage', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'}, + }, + ), ), InkWell( child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'push flutter widget', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: Text( + 'push flutter widget', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), onTap: () { Navigator.push<dynamic>( - context, MaterialPageRoute<dynamic>(builder: (_) => PushWidget())); + context, + MaterialPageRoute<dynamic>(builder: (_) => PushWidget()), + ); }, ), InkWell( child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open flutter fragment page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: Text( + 'open flutter fragment page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), onTap: () => - FlutterBoost.singleton.open("sample://flutterFragmentPage"), + FlutterBoost.singleton.open('sample://flutterFragmentPage'), ), ], ), @@ -156,15 +167,15 @@ class FlutterRouteWidget extends StatelessWidget { } class FragmentRouteWidget extends StatelessWidget { - final Map params; + const FragmentRouteWidget(this.params); - FragmentRouteWidget(this.params); + final Map<String, dynamic> params; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('flutter_boost_example'), + title: const Text('flutter_boost_example'), ), body: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -172,7 +183,7 @@ class FragmentRouteWidget extends StatelessWidget { Container( margin: const EdgeInsets.only(top: 80.0), child: Text( - "This is a flutter fragment", + 'This is a flutter fragment', style: TextStyle(fontSize: 28.0, color: Colors.blue), ), alignment: AlignmentDirectional.center, @@ -180,7 +191,7 @@ class FragmentRouteWidget extends StatelessWidget { Container( margin: const EdgeInsets.only(top: 32.0), child: Text( - params['tag'] ?? '', + '${params['tag']}' ?? '', style: TextStyle(fontSize: 28.0, color: Colors.red), ), alignment: AlignmentDirectional.center, @@ -188,37 +199,40 @@ class FragmentRouteWidget extends StatelessWidget { Expanded(child: Container()), InkWell( child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open native page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - onTap: () => FlutterBoost.singleton.open("sample://nativePage"), + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: Text( + 'open native page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), + onTap: () => FlutterBoost.singleton.open('sample://nativePage'), ), InkWell( child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open flutter page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - onTap: () => FlutterBoost.singleton.open("sample://flutterPage"), + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: Text( + 'open flutter page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), + onTap: () => FlutterBoost.singleton.open('sample://flutterPage'), ), InkWell( child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 80.0), - color: Colors.yellow, - child: Text( - 'open flutter fragment page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 80.0), + color: Colors.yellow, + child: Text( + 'open flutter fragment page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), onTap: () => - FlutterBoost.singleton.open("sample://flutterFragmentPage"), + FlutterBoost.singleton.open('sample://flutterFragmentPage'), ) ], ), @@ -234,15 +248,8 @@ class PushWidget extends StatefulWidget { class _PushWidgetState extends State<PushWidget> { VoidCallback _backPressedListenerUnsub; - @override - void initState() { - // TODO: implement initState - super.initState(); - } - @override void didChangeDependencies() { - // TODO: implement didChangeDependencies super.didChangeDependencies(); // if (_backPressedListenerUnsub == null) { @@ -258,13 +265,12 @@ class _PushWidgetState extends State<PushWidget> { @override void dispose() { - // TODO: implement dispose super.dispose(); _backPressedListenerUnsub?.call(); } @override Widget build(BuildContext context) { - return FlutterRouteWidget(message: "Pushed Widget"); + return const FlutterRouteWidget(message: 'Pushed Widget'); } } diff --git a/example_swift/lib/test_input.dart b/example_swift/lib/test_input.dart index dbb8d3148d2de8709e96fd233651de31b924fc94..070408a3c9ce6f0ead7263b57837d8d0ce412d90 100644 --- a/example_swift/lib/test_input.dart +++ b/example_swift/lib/test_input.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; class TestPage extends StatefulWidget { - TestPage({Key key, this.title = "Input Test"}) : super(key: key); + const TestPage({ + Key key, + this.title = 'Input Test', + }) : super(key: key); final String title; @@ -18,100 +21,87 @@ class _TestPageState extends State<TestPage> { }); } - @override - void initState() { - // TODO: implement initState - super.initState(); - } - @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), + appBar: AppBar(title: Text(widget.title)), body: SafeArea( - bottom: false, - child: ListView( - children: <Widget>[ - Container( - child: Text( - 'You have pushed the button this many times:', + bottom: false, + child: ListView( + children: <Widget>[ + Container( + child: const Text( + 'You have pushed the button this many times:', + ), + margin: const EdgeInsets.all(8.0), + alignment: Alignment.center, ), - margin: const EdgeInsets.all(8.0), - alignment: Alignment.center, - ), - Container( - child: Text( - '$_counter', - style: Theme.of(context).textTheme.display1, + Container( + child: Text( + '$_counter', + style: Theme.of(context).textTheme.display1, + ), + margin: const EdgeInsets.all(8.0), + alignment: Alignment.center, ), - margin: const EdgeInsets.all(8.0), - alignment: Alignment.center, - ), - Container( - child: TextField( - minLines: 2, - maxLines: 10, + Container( + child: const TextField(minLines: 2, maxLines: 10), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - TestTextField(), - Container( - child: Container( - color: Colors.red, - width: double.infinity, - height: 128.0, + TestTextField(), + Container( + child: Container( + color: Colors.red, + width: double.infinity, + height: 128.0, + ), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - Container( - child: Container( - color: Colors.orange, - width: double.infinity, - height: 128.0, + Container( + child: Container( + color: Colors.orange, + width: double.infinity, + height: 128.0, + ), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - Container( - child: Container( - color: Colors.green, - width: double.infinity, - height: 128.0, + Container( + child: Container( + color: Colors.green, + width: double.infinity, + height: 128.0, + ), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - Container( - child: Container( - color: Colors.blue, - width: double.infinity, - height: 128.0, + Container( + child: Container( + color: Colors.blue, + width: double.infinity, + height: 128.0, + ), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - Container( - child: Container( - color: Colors.yellow, - width: double.infinity, - height: 128.0, + Container( + child: Container( + color: Colors.yellow, + width: double.infinity, + height: 128.0, + ), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - Container( - child: TextField( - minLines: 2, - maxLines: 10, + Container( + child: const TextField(minLines: 2, maxLines: 10), + padding: const EdgeInsets.all(8.0), ), - padding: const EdgeInsets.all(8.0), - ), - TestTextField(), - ], - )), + TestTextField(), + ], + ), + ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. + ), ); } } @@ -123,25 +113,24 @@ class TestTextField extends StatefulWidget { class _TestTextFieldState extends State<TestTextField> { FocusNode _node; - PersistentBottomSheetController _controller; + PersistentBottomSheetController<dynamic> _controller; @override void initState() { - // TODO: implement initState super.initState(); _node = FocusNode(); _node.addListener(() { if (_node.hasFocus) { print('showBottomSheet'); - _controller = Scaffold.of(context) - .showBottomSheet<dynamic>((BuildContext ctx) => Container( - width: double.infinity, - height: 36.0, - color: Colors.deepPurple, - )); + _controller = Scaffold.of(context).showBottomSheet<dynamic>( + (BuildContext ctx) => Container( + width: double.infinity, + height: 36.0, + color: Colors.deepPurple, + ), + ); } else { if (_controller != null) { - //Navigator.of(context).pop(); print('closeBottomSheet'); _controller.close(); } diff --git a/lib/channel/boost_channel.dart b/lib/channel/boost_channel.dart index 9324b2ebe082c68f08ad5f02519742220c031c64..d85d01941027ddd10875403bb620140217caf05b 100755 --- a/lib/channel/boost_channel.dart +++ b/lib/channel/boost_channel.dart @@ -24,30 +24,30 @@ import 'dart:async'; import 'dart:ui'; -import 'package:flutter/services.dart'; -typedef Future<dynamic> EventListener(String name, Map arguments); -typedef Future<dynamic> MethodHandler(MethodCall call); +import 'package:flutter/services.dart'; -class BoostChannel { - final MethodChannel _methodChannel = MethodChannel("flutter_boost"); +typedef EventListener = Future<dynamic> Function( + String name, Map<String, dynamic> arguments); - final Map<String, List<EventListener>> _eventListeners = Map(); - final Set<MethodHandler> _methodHandlers = Set(); +typedef MethodHandler = Future<dynamic> Function(MethodCall call); +class BoostChannel { BoostChannel() { _methodChannel.setMethodCallHandler((MethodCall call) { - if (call.method == "__event__") { - String name = call.arguments["name"]; - Map arg = call.arguments["arguments"]; - List<EventListener> list = _eventListeners[name]; + if (call.method == '__event__') { + final String name = call.arguments['name'] as String; + final Map<String, dynamic> arg = + (call.arguments['arguments'] as Map<dynamic, dynamic>) + ?.cast<String, dynamic>(); + final List<EventListener> list = _eventListeners[name]; if (list != null) { - for (EventListener l in list) { + for (final EventListener l in list) { l(name, arg); } } } else { - for (MethodHandler handler in _methodHandlers) { + for (final MethodHandler handler in _methodHandlers) { handler(call); } } @@ -56,37 +56,41 @@ class BoostChannel { }); } - void sendEvent(String name, Map arguments) { + final MethodChannel _methodChannel = const MethodChannel('flutter_boost'); + + final Map<String, List<EventListener>> _eventListeners = + <String, List<EventListener>>{}; + final Set<MethodHandler> _methodHandlers = <MethodHandler>{}; + + void sendEvent(String name, Map<String, dynamic> arguments) { if (name == null) { return; } - if (arguments == null) { - arguments = Map<dynamic, dynamic>(); - } + arguments ??= <String, dynamic>{}; - Map msg = Map<dynamic, dynamic>(); - msg["name"] = name; - msg["arguments"] = arguments; - _methodChannel.invokeMethod<dynamic>("__event__", msg); + final Map<String, dynamic> msg = <String, dynamic>{}; + msg['name'] = name; + msg['arguments'] = arguments; + _methodChannel.invokeMethod<dynamic>('__event__', msg); } Future<T> invokeMethod<T>(String method, [dynamic arguments]) async { - assert(method != "__event__"); + assert(method != '__event__'); return _methodChannel.invokeMethod<T>(method, arguments); } Future<List<T>> invokeListMethod<T>(String method, [dynamic arguments]) async { - assert(method != "__event__"); + assert(method != '__event__'); return _methodChannel.invokeListMethod<T>(method, arguments); } Future<Map<K, V>> invokeMapMethod<K, V>(String method, [dynamic arguments]) async { - assert(method != "__event__"); + assert(method != '__event__'); return _methodChannel.invokeMapMethod<K, V>(method, arguments); } @@ -94,9 +98,11 @@ class BoostChannel { VoidCallback addEventListener(String name, EventListener listener) { assert(name != null && listener != null); - List<EventListener> list = _eventListeners[name]; + List<EventListener> list; + list = _eventListeners[name]; + if (list == null) { - list = List(); + list = <EventListener>[]; _eventListeners[name] = list; } diff --git a/lib/container/boost_container.dart b/lib/container/boost_container.dart index 7fe3174c286964acaf017a95adda088a952d191a..c522e6eb4c343f5cdd8959b036862734238c1254 100755 --- a/lib/container/boost_container.dart +++ b/lib/container/boost_container.dart @@ -22,10 +22,11 @@ * THE SOFTWARE. */ import 'package:flutter/material.dart'; -import 'container_manager.dart'; + import '../flutter_boost.dart'; -import 'boost_page_route.dart'; import '../support/logger.dart'; +import 'boost_page_route.dart'; +import 'container_manager.dart'; enum ContainerLifeCycle { Init, @@ -37,28 +38,31 @@ enum ContainerLifeCycle { Foreground } -typedef void BoostContainerLifeCycleObserver( - ContainerLifeCycle state, BoostContainerSettings settings); +typedef BoostContainerLifeCycleObserver = void Function( + ContainerLifeCycle state, + BoostContainerSettings settings, +); class BoostContainer extends Navigator { - final BoostContainerSettings settings; - - const BoostContainer( - {GlobalKey<BoostContainerState> key, - this.settings = const BoostContainerSettings(), - String initialRoute, - RouteFactory onGenerateRoute, - RouteFactory onUnknownRoute, - List<NavigatorObserver> observers}) - : super( - key: key, - initialRoute: initialRoute, - onGenerateRoute: onGenerateRoute, - onUnknownRoute: onUnknownRoute, - observers: observers); - - factory BoostContainer.copy(Navigator navigator, - [BoostContainerSettings settings = const BoostContainerSettings()]) => + const BoostContainer({ + GlobalKey<BoostContainerState> key, + this.settings = const BoostContainerSettings(), + String initialRoute, + RouteFactory onGenerateRoute, + RouteFactory onUnknownRoute, + List<NavigatorObserver> observers, + }) : super( + key: key, + initialRoute: initialRoute, + onGenerateRoute: onGenerateRoute, + onUnknownRoute: onUnknownRoute, + observers: observers, + ); + + factory BoostContainer.copy( + Navigator navigator, [ + BoostContainerSettings settings = const BoostContainerSettings(), + ]) => BoostContainer( key: GlobalKey<BoostContainerState>(), settings: settings, @@ -69,28 +73,34 @@ class BoostContainer extends Navigator { ); factory BoostContainer.obtain( - Navigator navigator, BoostContainerSettings settings) => + Navigator navigator, + BoostContainerSettings settings, + ) => BoostContainer( - key: GlobalKey<BoostContainerState>(), - settings: settings, - onGenerateRoute: (RouteSettings routeSettings) { - if (routeSettings.name == '/') { - return BoostPageRoute<dynamic>( - pageName: settings.name, - params: settings.params, - uniqueId: settings.uniqueId, - animated: false, - settings: routeSettings, - builder: settings.builder); - } else { - return navigator.onGenerateRoute(routeSettings); - } - }, - observers: <NavigatorObserver>[ - ContainerNavigatorObserver.bindContainerManager(), - HeroController(), - ], - onUnknownRoute: navigator.onUnknownRoute); + key: GlobalKey<BoostContainerState>(), + settings: settings, + onGenerateRoute: (RouteSettings routeSettings) { + if (routeSettings.name == '/') { + return BoostPageRoute<dynamic>( + pageName: settings.name, + params: settings.params, + uniqueId: settings.uniqueId, + animated: false, + settings: routeSettings, + builder: settings.builder, + ); + } else { + return navigator.onGenerateRoute(routeSettings); + } + }, + observers: <NavigatorObserver>[ + ContainerNavigatorObserver.bindContainerManager(), + HeroController(), + ], + onUnknownRoute: navigator.onUnknownRoute, + ); + + final BoostContainerSettings settings; @override BoostContainerState createState() => BoostContainerState(); @@ -121,7 +131,7 @@ class BoostContainerState extends NavigatorState { String get name => widget.settings.name; - Map get params => widget.settings.params; + Map<String, dynamic> get params => widget.settings.params; BoostContainerSettings get settings => widget.settings; @@ -138,7 +148,7 @@ class BoostContainerState extends NavigatorState { ContainerNavigatorObserver findContainerNavigatorObserver( Navigator navigator) { - for (NavigatorObserver observer in navigator.observers) { + for (final NavigatorObserver observer in navigator.observers) { if (observer is ContainerNavigatorObserver) { return observer; } @@ -153,11 +163,6 @@ class BoostContainerState extends NavigatorState { backPressedHandler = () => maybePop(); } - @override - void didUpdateWidget(Navigator oldWidget) { - super.didUpdateWidget(oldWidget); - } - @override void dispose() { routerHistory.clear(); @@ -172,7 +177,7 @@ class BoostContainerState extends NavigatorState { @override Future<bool> maybePop<T extends Object>([T result]) async { - final Route<T> route = routerHistory.last; + final Route<T> route = routerHistory.last as Route<T>; final RoutePopDisposition disposition = await route.willPop(); if (mounted) { switch (disposition) { @@ -199,7 +204,7 @@ class BoostContainerState extends NavigatorState { } if (canPop()) { - super.pop<T>(result); + super.pop<T>(result); } else { if (T is Map<String, dynamic>) { FlutterBoost.singleton @@ -216,10 +221,10 @@ class BoostContainerState extends NavigatorState { Route<T> newRoute; if (FlutterBoost.containerManager.prePushRoute != null) { newRoute = FlutterBoost.containerManager - .prePushRoute(name, uniqueId, params, route); + .prePushRoute<T>(name, uniqueId, params, route); } - Future<T> future = super.push<T>(newRoute ?? route); + final Future<T> future = super.push<T>(newRoute ?? route); routerHistory.add(route); @@ -233,25 +238,30 @@ class BoostContainerState extends NavigatorState { VoidCallback addLifeCycleObserver(BoostContainerLifeCycleObserver observer) { return FlutterBoost.singleton.addBoostContainerLifeCycleObserver( - (ContainerLifeCycle state, BoostContainerSettings settings) { - if (settings.uniqueId == uniqueId) { - observer(state, settings); - } - }); + ( + ContainerLifeCycle state, + BoostContainerSettings settings, + ) { + if (settings.uniqueId == uniqueId) { + observer(state, settings); + } + }, + ); } } class BoostContainerSettings { + const BoostContainerSettings({ + this.uniqueId = 'default', + this.name = 'default', + this.params, + this.builder, + }); + final String uniqueId; final String name; - final Map params; + final Map<String, dynamic> params; final WidgetBuilder builder; - - const BoostContainerSettings( - {this.uniqueId = 'default', - this.name = 'default', - this.params, - this.builder}); } class ContainerElement extends StatefulElement { @@ -259,13 +269,13 @@ class ContainerElement extends StatefulElement { } class ContainerNavigatorObserver extends NavigatorObserver { - static final Set<NavigatorObserver> boostObservers = Set<NavigatorObserver>(); - ContainerNavigatorObserver(); factory ContainerNavigatorObserver.bindContainerManager() => ContainerNavigatorObserver(); + static final Set<NavigatorObserver> boostObservers = <NavigatorObserver>{}; + VoidCallback addBoostNavigatorObserver(NavigatorObserver observer) { boostObservers.add(observer); @@ -278,28 +288,28 @@ class ContainerNavigatorObserver extends NavigatorObserver { @override void didPush(Route<dynamic> route, Route<dynamic> previousRoute) { - for (NavigatorObserver observer in boostObservers) { + for (final NavigatorObserver observer in boostObservers) { observer.didPush(route, previousRoute); } } @override void didPop(Route<dynamic> route, Route<dynamic> previousRoute) { - for (NavigatorObserver observer in boostObservers) { + for (final NavigatorObserver observer in boostObservers) { observer.didPop(route, previousRoute); } } @override void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) { - for (NavigatorObserver observer in boostObservers) { + for (final NavigatorObserver observer in boostObservers) { observer.didRemove(route, previousRoute); } } @override void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) { - for (NavigatorObserver observer in boostObservers) { + for (final NavigatorObserver observer in boostObservers) { observer.didReplace(newRoute: newRoute, oldRoute: oldRoute); } } diff --git a/lib/container/boost_page_route.dart b/lib/container/boost_page_route.dart index 466d7d5b71738ae3662b795233df18d0df854413..e3c4d8f4332c5fbbf12b52d10a71b7ae59c47f86 100755 --- a/lib/container/boost_page_route.dart +++ b/lib/container/boost_page_route.dart @@ -25,26 +25,25 @@ import 'package:flutter/widgets.dart'; import 'package:flutter/material.dart'; -typedef Widget PageBuilder(String pageName, Map params, String uniqueId); +typedef PageBuilder = Widget Function( + String pageName, Map<String, dynamic> params, String uniqueId); class BoostPageRoute<T> extends MaterialPageRoute<T> { + BoostPageRoute({ + this.pageName, + this.params, + this.uniqueId, + this.animated, + WidgetBuilder builder, + RouteSettings settings, + }) : super(builder: builder, settings: settings); + final String pageName; final String uniqueId; - final Map params; + final Map<String, dynamic> params; final bool animated; - final WidgetBuilder builder; - final RouteSettings settings; - - final Set<VoidCallback> backPressedListeners = Set<VoidCallback>(); - BoostPageRoute( - {this.pageName, - this.params, - this.uniqueId, - this.animated, - this.builder, - this.settings}) - : super(builder: builder, settings: settings); + final Set<VoidCallback> backPressedListeners = <VoidCallback>{}; static BoostPageRoute<T> of<T>(BuildContext context) { final Route<T> route = ModalRoute.of(context); diff --git a/lib/container/container_coordinator.dart b/lib/container/container_coordinator.dart index 59931a14446db700768f2611f5c041b9c4eb73d4..655dc0cb8999bc0fb03562cbc4c1cf1e51d3b5ab 100755 --- a/lib/container/container_coordinator.dart +++ b/lib/container/container_coordinator.dart @@ -27,12 +27,25 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/semantics.dart'; import 'package:flutter/services.dart'; + import '../channel/boost_channel.dart'; -import 'boost_container.dart'; import '../flutter_boost.dart'; import '../support/logger.dart'; +import 'boost_container.dart'; class ContainerCoordinator { + ContainerCoordinator(BoostChannel channel) : assert(_instance == null) { + _instance = this; + + channel + ..addEventListener( + 'lifecycle', + (String name, Map<String, dynamic> arguments) => + _onChannelEvent(arguments), + ) + ..addMethodHandler((MethodCall call) => _onMethodCall(call)); + } + static ContainerCoordinator get singleton => _instance; static ContainerCoordinator _instance; @@ -40,19 +53,11 @@ class ContainerCoordinator { final Map<String, PageBuilder> _pageBuilders = <String, PageBuilder>{}; PageBuilder _defaultPageBuilder; - ContainerCoordinator(BoostChannel channel) { - assert(_instance == null); - - _instance = this; - - channel.addEventListener("lifecycle", - (String name, Map arguments) => _onChannelEvent(arguments)); - - channel.addMethodHandler((MethodCall call) => _onMethodCall(call)); - } - BoostContainerSettings _createContainerSettings( - String name, Map params, String pageId) { + String name, + Map<String, dynamic> params, + String pageId, + ) { Widget page; final BoostContainerSettings routeSettings = BoostContainerSettings( @@ -60,12 +65,12 @@ class ContainerCoordinator { name: name, params: params, builder: (BuildContext ctx) { - //Try to build a page using keyed builder. + // Try to build a page using keyed builder. if (_pageBuilders[name] != null) { page = _pageBuilders[name](name, params, pageId); } - //Build a page using default builder. + // Build a page using default builder. if (page == null && _defaultPageBuilder != null) { page = _defaultPageBuilder(name, params, pageId); } @@ -79,12 +84,12 @@ class ContainerCoordinator { return routeSettings; } - //Register a default page builder. + /// Register a default page builder. void registerDefaultPageBuilder(PageBuilder builder) { _defaultPageBuilder = builder; } - //Register page builder for a key. + /// Register page builder for a key. void registerPageBuilder(String pageName, PageBuilder builder) { if (pageName != null && builder != null) { _pageBuilders[pageName] = builder; @@ -98,41 +103,35 @@ class ContainerCoordinator { } Future<dynamic> _onChannelEvent(dynamic event) { - if (event is Map) { - Map map = event; - final String type = map['type']; + if (event is Map<String, dynamic>) { + final Map<String, dynamic> map = event; + final String type = map['type'] as String; Logger.log('onEvent $type'); switch (type) { - //Handler back key pressed event. + // Handler back key pressed event. case 'backPressedCallback': - { - final String id = map['uniqueId']; - FlutterBoost.containerManager - ?.containerStateOf(id) - ?.performBackPressed(); - } + final String id = map['uniqueId'] as String; + FlutterBoost.containerManager + ?.containerStateOf(id) + ?.performBackPressed(); break; - //Enter foregroud + // Enter foreground case 'foreground': - { - FlutterBoost.containerManager?.setForeground(); - } + FlutterBoost.containerManager?.setForeground(); break; - //Enter background + // Enter background case 'background': - { - FlutterBoost.containerManager?.setBackground(); - } + FlutterBoost.containerManager?.setBackground(); break; - //Schedule a frame. + // Schedule a frame. case 'scheduleFrame': - { - WidgetsBinding.instance.scheduleForcedFrame(); - Future<dynamic>.delayed(Duration(milliseconds: 250), - () => WidgetsBinding.instance.scheduleFrame()); - } + WidgetsBinding.instance.scheduleForcedFrame(); + Future<dynamic>.delayed( + const Duration(milliseconds: 250), + () => WidgetsBinding.instance.scheduleFrame(), + ); break; } } @@ -141,72 +140,52 @@ class ContainerCoordinator { } Future<dynamic> _onMethodCall(MethodCall call) { - Logger.log("onMetohdCall ${call.method}"); + Logger.log('onMetohdCall ${call.method}'); + + final String pageName = call.arguments['pageName'] as String; + final Map<String, dynamic> params = + (call.arguments['params'] as Map<dynamic, dynamic>) + ?.cast<String, dynamic>(); + final String uniqueId = call.arguments['uniqueId'] as String; switch (call.method) { - case "didInitPageContainer": - { - String pageName = call.arguments["pageName"]; - Map params = call.arguments["params"]; - String uniqueId = call.arguments["uniqueId"]; - _nativeContainerDidInit(pageName, params, uniqueId); - } + case 'didInitPageContainer': + _nativeContainerDidInit(pageName, params, uniqueId); break; - case "willShowPageContainer": - { - String pageName = call.arguments["pageName"]; - Map params = call.arguments["params"]; - String uniqueId = call.arguments["uniqueId"]; - _nativeContainerWillShow(pageName, params, uniqueId); - } + case 'willShowPageContainer': + _nativeContainerWillShow(pageName, params, uniqueId); break; - case "didShowPageContainer": - { - String pageName = call.arguments["pageName"]; - Map params = call.arguments["params"]; - String uniqueId = call.arguments["uniqueId"]; - nativeContainerDidShow(pageName, params, uniqueId); - } + case 'didShowPageContainer': + nativeContainerDidShow(pageName, params, uniqueId); break; - case "willDisappearPageContainer": - { - String pageName = call.arguments["pageName"]; - Map params = call.arguments["params"]; - String uniqueId = call.arguments["uniqueId"]; - _nativeContainerWillDisappear(pageName, params, uniqueId); - } + case 'willDisappearPageContainer': + _nativeContainerWillDisappear(pageName, params, uniqueId); break; - case "didDisappearPageContainer": - { - String pageName = call.arguments["pageName"]; - Map params = call.arguments["params"]; - String uniqueId = call.arguments["uniqueId"]; - _nativeContainerDidDisappear(pageName, params, uniqueId); - } + case 'didDisappearPageContainer': + _nativeContainerDidDisappear(pageName, params, uniqueId); break; - case "willDeallocPageContainer": - { - String pageName = call.arguments["pageName"]; - Map params = call.arguments["params"]; - String uniqueId = call.arguments["uniqueId"]; - _nativeContainerWillDealloc(pageName, params, uniqueId); - } + case 'willDeallocPageContainer': + _nativeContainerWillDealloc(pageName, params, uniqueId); break; - case "onNativePageResult": - {} + case 'onNativePageResult': break; } return Future<dynamic>(() {}); } - bool _nativeContainerWillShow(String name, Map params, String pageId) { + bool _nativeContainerWillShow( + String name, + Map<String, dynamic> params, + String pageId, + ) { if (FlutterBoost.containerManager?.containsContainer(pageId) != true) { - FlutterBoost.containerManager - ?.pushContainer(_createContainerSettings(name, params, pageId)); + FlutterBoost.containerManager?.pushContainer( + _createContainerSettings(name, params, pageId), + ); } - //TODO, 需è¦éªŒè¯androidä»£ç æ˜¯å¦ä¹Ÿå¯ä»¥ç§»åˆ°è¿™é‡Œ + // TODO(unknown): 需è¦éªŒè¯androidä»£ç æ˜¯å¦ä¹Ÿå¯ä»¥ç§»åˆ°è¿™é‡Œ if (Platform.isIOS) { try { final SemanticsOwner owner = @@ -221,72 +200,114 @@ class ContainerCoordinator { return true; } - bool nativeContainerDidShow(String name, Map params, String pageId) { + bool nativeContainerDidShow( + String name, + Map<String, dynamic> params, + String pageId, + ) { FlutterBoost.containerManager ?.showContainer(_createContainerSettings(name, params, pageId)); - //å¯¹æ— éšœç¢è¾…助模å¼çš„兼容 - try { - final SemanticsOwner owner = - WidgetsBinding.instance.pipelineOwner?.semanticsOwner; - final SemanticsNode root = owner?.rootSemanticsNode; - root?.detach(); - root?.attach(owner); - } catch (e) { - assert(false, e.toString()); + // Compatible to accessibility mode on Android. + if (Platform.isAndroid) { + try { + final SemanticsOwner owner = + WidgetsBinding.instance.pipelineOwner?.semanticsOwner; + final SemanticsNode root = owner?.rootSemanticsNode; + root?.detach(); + root?.attach(owner); + } catch (e) { + assert(false, e.toString()); + } } - performContainerLifeCycle(_createContainerSettings(name, params, pageId), - ContainerLifeCycle.Appear); + performContainerLifeCycle( + _createContainerSettings(name, params, pageId), + ContainerLifeCycle.Appear, + ); Logger.log( - 'native containner did show-$name,\nmanager dump:\n${FlutterBoost.containerManager?.dump()}'); + 'native containner did show-$name,\n' + 'manager dump:\n' + '${FlutterBoost.containerManager?.dump()}', + ); return true; } - bool _nativeContainerWillDisappear(String name, Map params, String pageId) { - performContainerLifeCycle(_createContainerSettings(name, params, pageId), - ContainerLifeCycle.WillDisappear); + bool _nativeContainerWillDisappear( + String name, + Map<String, dynamic> params, + String pageId, + ) { + performContainerLifeCycle( + _createContainerSettings(name, params, pageId), + ContainerLifeCycle.WillDisappear, + ); return true; } - bool _nativeContainerDidDisappear(String name, Map params, String pageId) { - performContainerLifeCycle(_createContainerSettings(name, params, pageId), - ContainerLifeCycle.Disappear); + bool _nativeContainerDidDisappear( + String name, + Map<String, dynamic> params, + String pageId, + ) { + performContainerLifeCycle( + _createContainerSettings(name, params, pageId), + ContainerLifeCycle.Disappear, + ); return true; } - bool _nativeContainerDidInit(String name, Map params, String pageId) { - performContainerLifeCycle(_createContainerSettings(name, params, pageId), - ContainerLifeCycle.Init); + bool _nativeContainerDidInit( + String name, + Map<String, dynamic> params, + String pageId, + ) { + performContainerLifeCycle( + _createContainerSettings(name, params, pageId), + ContainerLifeCycle.Init, + ); return true; } - bool _nativeContainerWillDealloc(String name, Map params, String pageId) { + bool _nativeContainerWillDealloc( + String name, Map<String, dynamic> params, String pageId) { try { - performContainerLifeCycle(_createContainerSettings(name, params, pageId), - ContainerLifeCycle.Destroy); + performContainerLifeCycle( + _createContainerSettings(name, params, pageId), + ContainerLifeCycle.Destroy, + ); } catch (e) { Logger.log('nativeContainerWillDealloc error: $e'); } FlutterBoost.containerManager?.remove(pageId); Logger.log( - 'native containner dealloc for $name, \n manager dump:\n${FlutterBoost.containerManager?.dump()}'); + 'native containner dealloc for $name, \n' + 'manager dump:\n' + '${FlutterBoost.containerManager?.dump()}', + ); return true; } static void performContainerLifeCycle( - BoostContainerSettings settings, ContainerLifeCycle lifeCycle) { - for (BoostContainerLifeCycleObserver observer in FlutterBoost + BoostContainerSettings settings, + ContainerLifeCycle lifeCycle, + ) { + final Set<BoostContainerLifeCycleObserver> observers = FlutterBoost .singleton.observersHolder - .observersOf<BoostContainerLifeCycleObserver>()) { + .observersOf<BoostContainerLifeCycleObserver>(); + + for (final BoostContainerLifeCycleObserver observer in observers) { observer(lifeCycle, settings); } Logger.log( - 'BoostContainerLifeCycleObserver container:${settings.name} lifeCycle:$lifeCycle'); + 'BoostContainerLifeCycleObserver' + 'container:${settings.name}' + 'lifeCycle:$lifeCycle', + ); } } diff --git a/lib/container/container_manager.dart b/lib/container/container_manager.dart index 562c9645f15a4b8d7f426e3d920b6b986db2da99..30b1499d16e07295d9c50357de724e5311d7575b 100755 --- a/lib/container/container_manager.dart +++ b/lib/container/container_manager.dart @@ -23,10 +23,11 @@ */ import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; -import 'boost_container.dart'; -import 'container_coordinator.dart'; + import '../flutter_boost.dart'; import '../support/logger.dart'; +import 'boost_container.dart'; +import 'container_coordinator.dart'; enum ContainerOperation { Push, Onstage, Pop, Remove } @@ -35,12 +36,16 @@ typedef BoostContainerObserver = void Function( @immutable class BoostContainerManager extends StatefulWidget { + const BoostContainerManager({ + Key key, + this.initNavigator, + this.prePushRoute, + this.postPushRoute, + }) : super(key: key); + final Navigator initNavigator; final PrePushRoute prePushRoute; final PostPushRoute postPushRoute; - const BoostContainerManager( - {Key key, this.initNavigator, this.prePushRoute, this.postPushRoute}) - : super(key: key); @override ContainerManagerState createState() => ContainerManagerState(); @@ -76,15 +81,15 @@ class ContainerManagerState extends State<BoostContainerManager> { bool get foreground => _foreground; - //Number of containers. + // Number of containers. 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; - //Current visible container. + // Current visible container. BoostContainerState get onstageContainer => _stateOf(_onstage); BoostContainerState get subContainer => @@ -118,8 +123,7 @@ class ContainerManagerState extends State<BoostContainerManager> { } BoostContainerState _stateOf(BoostContainer container) { - if (container.key != null && - container.key is GlobalKey<BoostContainerState>) { + if (container.key is GlobalKey<BoostContainerState>) { final GlobalKey<BoostContainerState> globalKey = container.key as GlobalKey<BoostContainerState>; return globalKey.currentState; @@ -133,7 +137,7 @@ class ContainerManagerState extends State<BoostContainerManager> { void _onShownContainerChanged(String old, String now) { Logger.log('onShownContainerChanged old:$old now:$now'); - Map<String, dynamic> properties = new Map<String, dynamic>(); + final Map<String, dynamic> properties = <String, dynamic>{}; properties['newName'] = now; properties['oldName'] = old; @@ -149,7 +153,7 @@ class ContainerManagerState extends State<BoostContainerManager> { } if (_leastEntries != null && _leastEntries.isNotEmpty) { - for (_ContainerOverlayEntry entry in _leastEntries) { + for (final _ContainerOverlayEntry entry in _leastEntries) { entry.remove(); } } @@ -223,7 +227,7 @@ class ContainerManagerState extends State<BoostContainerManager> { setState(() {}); - for (BoostContainerObserver observer in FlutterBoost + for (final BoostContainerObserver observer in FlutterBoost .singleton.observersHolder .observersOf<BoostContainerObserver>()) { observer(ContainerOperation.Onstage, _onstage.settings); @@ -265,7 +269,7 @@ class ContainerManagerState extends State<BoostContainerManager> { setState(() {}); - for (BoostContainerObserver observer in FlutterBoost + for (final BoostContainerObserver observer in FlutterBoost .singleton.observersHolder .observersOf<BoostContainerObserver>()) { observer(ContainerOperation.Push, _onstage.settings); @@ -280,9 +284,11 @@ class ContainerManagerState extends State<BoostContainerManager> { _onstage = _offstage.removeLast(); setState(() {}); - for (BoostContainerObserver observer in FlutterBoost + final Set<BoostContainerObserver> observers = FlutterBoost .singleton.observersHolder - .observersOf<BoostContainerObserver>()) { + .observersOf<BoostContainerObserver>(); + + for (final BoostContainerObserver observer in observers) { observer(ContainerOperation.Pop, old.settings); } @@ -294,32 +300,34 @@ class ContainerManagerState extends State<BoostContainerManager> { pop(); } else { final BoostContainer container = _offstage.firstWhere( - (BoostContainer container) => container.settings.uniqueId == uniqueId, - orElse: () => null); + (BoostContainer container) => container.settings.uniqueId == uniqueId, + orElse: () => null, + ); if (container != null) { _offstage.remove(container); setState(() {}); - for (BoostContainerObserver observer in FlutterBoost + final Set<BoostContainerObserver> observers = FlutterBoost .singleton.observersHolder - .observersOf<BoostContainerObserver>()) { + .observersOf<BoostContainerObserver>(); + + for (final BoostContainerObserver observer in observers) { observer(ContainerOperation.Remove, container.settings); } Logger.log('ContainerObserver#2 didRemove'); } } - - return null; } bool canPop() => _offstage.isNotEmpty; String dump() { - String info = 'onstage#:\n ${_onstage?.desc()}\noffstage#:'; + String info; + info = 'onstage#:\n ${_onstage?.desc()}\noffstage#:'; - for (BoostContainer container in _offstage.reversed) { + for (final BoostContainer container in _offstage.reversed) { info = '$info\n ${container?.desc()}'; } @@ -328,21 +336,21 @@ class ContainerManagerState extends State<BoostContainerManager> { } class _ContainerOverlayEntry extends OverlayEntry { - bool _removed = false; _ContainerOverlayEntry(BoostContainer container) : super( - builder: (BuildContext ctx) => container, - opaque: true, - maintainState: true); + builder: (BuildContext ctx) => container, + opaque: true, + maintainState: true, + ); + + bool _removed = false; @override void remove() { assert(!_removed); - if (_removed) { return; } - _removed = true; super.remove(); } diff --git a/lib/flutter_boost.dart b/lib/flutter_boost.dart index 8552cd7e01bd06ef3f486d4ab3cb4cab8e8a4e6c..f6dad0e190fd13ade32e038c3b83803de8a609a1 100755 --- a/lib/flutter_boost.dart +++ b/lib/flutter_boost.dart @@ -25,58 +25,79 @@ import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; -import 'container/boost_container.dart'; -import 'container/container_manager.dart'; import 'channel/boost_channel.dart'; +import 'container/boost_container.dart'; import 'container/container_coordinator.dart'; +import 'container/container_manager.dart'; import 'observers_holders.dart'; export 'container/boost_container.dart'; export 'container/container_manager.dart'; -typedef Widget PageBuilder(String pageName, Map params, String uniqueId); +typedef PageBuilder = Widget Function( + String pageName, Map<String, dynamic> params, String uniqueId); -typedef Route PrePushRoute( - String url, String uniqueId, Map params, Route route); +typedef PrePushRoute = Route<T> Function<T>(String url, String uniqueId, + Map<String, dynamic> params, Route<dynamic> route); -typedef void PostPushRoute( - String url, String uniqueId, Map params, Route route, Future result); +typedef PostPushRoute = void Function( + String url, + String uniqueId, + Map<String, dynamic> params, + Route<dynamic> route, + Future<dynamic> result, +); class FlutterBoost { + FlutterBoost() { + ContainerCoordinator(_boostChannel); + } + static final FlutterBoost _instance = FlutterBoost(); - final GlobalKey<ContainerManagerState> containerManagerKey = - GlobalKey<ContainerManagerState>(); - final ObserversHolder _observersHolder = ObserversHolder(); - final BoostChannel _boostChannel = BoostChannel(); static FlutterBoost get singleton => _instance; static ContainerManagerState get containerManager => _instance.containerManagerKey.currentState; - static void onPageStart() { - WidgetsBinding.instance.addPostFrameCallback((_) { - singleton.channel.invokeMethod<Map>('pageOnStart').then((Map pageInfo) { - if (pageInfo == null || pageInfo.isEmpty) return; + final GlobalKey<ContainerManagerState> containerManagerKey = + GlobalKey<ContainerManagerState>(); + final ObserversHolder _observersHolder = ObserversHolder(); + final BoostChannel _boostChannel = BoostChannel(); - if (pageInfo.containsKey("name") && - pageInfo.containsKey("params") && - pageInfo.containsKey("uniqueId")) { + static void onPageStart() { + WidgetsBinding.instance.addPostFrameCallback((Duration _) { + singleton.channel + .invokeMethod<Map<dynamic, dynamic>>('pageOnStart') + .then((Map<dynamic, dynamic> _pageInfo) { + final Map<String, dynamic> pageInfo = _pageInfo?.cast<String, dynamic>(); + if (pageInfo?.isEmpty ?? true) { + return; + } + if (pageInfo.containsKey('name') && + pageInfo.containsKey('params') && + pageInfo.containsKey('uniqueId')) { ContainerCoordinator.singleton.nativeContainerDidShow( - pageInfo["name"], pageInfo["params"], pageInfo["uniqueId"]); + pageInfo['name'] as String, + (pageInfo['params'] as Map<dynamic, dynamic>) + ?.cast<String, dynamic>(), + pageInfo['uniqueId'] as String, + ); } }); }); } - static TransitionBuilder init( - {TransitionBuilder builder, - PrePushRoute prePush, - PostPushRoute postPush}) { + static TransitionBuilder init({ + TransitionBuilder builder, + PrePushRoute prePush, + PostPushRoute postPush, + }) { if (Platform.isAndroid) { onPageStart(); } else if (Platform.isIOS) { + // TODO(AlexVincent525): 未解之谜 assert(() { () async { onPageStart(); @@ -89,10 +110,11 @@ class FlutterBoost { assert(child is Navigator, 'child must be Navigator, what is wrong?'); final BoostContainerManager manager = BoostContainerManager( - key: _instance.containerManagerKey, - initNavigator: child, - prePushRoute: prePush, - postPushRoute: postPush); + key: _instance.containerManagerKey, + initNavigator: child as Navigator, + prePushRoute: prePush, + postPushRoute: postPush, + ); if (builder != null) { return builder(context, manager); @@ -106,94 +128,95 @@ class FlutterBoost { BoostChannel get channel => _boostChannel; - FlutterBoost() { - ContainerCoordinator(_boostChannel); - } - - ///Register a default page builder. + /// Register a default page builder. void registerDefaultPageBuilder(PageBuilder builder) { ContainerCoordinator.singleton.registerDefaultPageBuilder(builder); } - ///Register a map builders + /// Register a map builders void registerPageBuilders(Map<String, PageBuilder> builders) { ContainerCoordinator.singleton.registerPageBuilders(builders); } - Future<Map<dynamic, dynamic>> open(String url, - {Map<dynamic, dynamic> urlParams, Map<dynamic, dynamic> exts}) { - Map<dynamic, dynamic> properties = new Map<dynamic, dynamic>(); - properties["url"] = url; - properties["urlParams"] = urlParams; - properties["exts"] = exts; + Future<Map<dynamic, dynamic>> open( + String url, { + Map<String, dynamic> urlParams, + Map<String, dynamic> exts, + }) { + final Map<String, dynamic> properties = <String, dynamic>{}; + properties['url'] = url; + properties['urlParams'] = urlParams; + properties['exts'] = exts; return channel.invokeMethod<Map<dynamic, dynamic>>('openPage', properties); } - Future<bool> close(String id, - {Map<dynamic, dynamic> result, Map<dynamic, dynamic> exts}) { + Future<bool> close( + String id, { + Map<String, dynamic> result, + Map<String, dynamic> exts, + }) { assert(id != null); - BoostContainerSettings settings = containerManager?.onstageSettings; - Map<dynamic, dynamic> properties = new Map<dynamic, dynamic>(); + final BoostContainerSettings settings = containerManager?.onstageSettings; + final Map<String, dynamic> properties = <String, dynamic>{}; - if (exts == null) { - exts = Map<dynamic, dynamic>(); - } + exts ??= <String, dynamic>{}; - exts["params"] = settings.params; + exts['params'] = settings.params; - if (!exts.containsKey("animated")) { - exts["animated"] = true; + if (!exts.containsKey('animated')) { + exts['animated'] = true; } - properties["uniqueId"] = id; + properties['uniqueId'] = id; if (result != null) { - properties["result"] = result; + properties['result'] = result; } if (exts != null) { - properties["exts"] = exts; + properties['exts'] = exts; } return channel.invokeMethod<bool>('closePage', properties); } - Future<bool> closeCurrent( - {Map<String, dynamic> result, Map<String, dynamic> exts}) { - BoostContainerSettings settings = containerManager?.onstageSettings; - if (exts == null) { - exts = Map<String, dynamic>(); - } - exts["params"] = settings.params; - if (!exts.containsKey("animated")) { - exts["animated"] = true; + Future<bool> closeCurrent({ + Map<String, dynamic> result, + Map<String, dynamic> exts, + }) { + final BoostContainerSettings settings = containerManager?.onstageSettings; + exts ??= <String, dynamic>{}; + exts['params'] = settings.params; + if (!exts.containsKey('animated')) { + exts['animated'] = true; } return close(settings.uniqueId, result: result, exts: exts); } - Future<bool> closeByContext(BuildContext context, - {Map<String, dynamic> result, Map<String, dynamic> exts}) { - BoostContainerSettings settings = containerManager?.onstageSettings; - if (exts == null) { - exts = Map<String, dynamic>(); - } - exts["params"] = settings.params; - if (!exts.containsKey("animated")) { - exts["animated"] = true; + Future<bool> closeByContext( + BuildContext context, { + Map<String, dynamic> result, + Map<String, dynamic> exts, + }) { + final BoostContainerSettings settings = containerManager?.onstageSettings; + exts ??= <String, dynamic>{}; + exts['params'] = settings.params; + if (!exts.containsKey('animated')) { + exts['animated'] = true; } return close(settings.uniqueId, result: result, exts: exts); } - ///register for Container changed callbacks + /// Register for Container changed callbacks VoidCallback addContainerObserver(BoostContainerObserver observer) => _observersHolder.addObserver<BoostContainerObserver>(observer); - ///register for Container lifecycle callbacks + /// Register for Container lifecycle callbacks VoidCallback addBoostContainerLifeCycleObserver( BoostContainerLifeCycleObserver observer) => _observersHolder.addObserver<BoostContainerLifeCycleObserver>(observer); - ///register callbacks for Navigators push & pop + /// Register callbacks for [Navigator.push] & [Navigator.pop] void addBoostNavigatorObserver(NavigatorObserver observer) => ContainerNavigatorObserver.boostObservers.add(observer); } diff --git a/lib/observers_holders.dart b/lib/observers_holders.dart index 7a9e60c855229499b3b35bbf5f3e93fa891600d7..923af6f36b8af17b35abee0e22f75d26196b51bf 100755 --- a/lib/observers_holders.dart +++ b/lib/observers_holders.dart @@ -24,10 +24,10 @@ import 'dart:ui'; class ObserversHolder { - final Map<String, Set<dynamic>> _observers = Map<String, Set<dynamic>>(); + final Map<String, Set<dynamic>> _observers = <String, Set<dynamic>>{}; VoidCallback addObserver<T>(T observer) { - final Set<T> set = _observers[T.toString()] ?? Set<T>(); + final Set<T> set = _observers[T.toString()] as Set<T> ?? <T>{}; set.add(observer); _observers[T.toString()] = set; @@ -40,5 +40,5 @@ class ObserversHolder { void cleanObservers<T>(T observer) => _observers[T.toString()]?.clear(); - Set<T> observersOf<T>() => _observers[T.toString()] ?? Set<T>(); + Set<T> observersOf<T>() => _observers[T.toString()] as Set<T> ?? <T>{}; } diff --git a/lib/support/logger.dart b/lib/support/logger.dart index fbcc81938f958eb98b1b277b3bfb9d3c53252d47..f98aa510a6ba69f671ee8414c94b3966073d4ff8 100755 --- a/lib/support/logger.dart +++ b/lib/support/logger.dart @@ -27,7 +27,6 @@ class Logger { print('FlutterBoost#$msg'); return true; }()); - //print('FlutterBoost=>$msg'); } static void error(String msg) { diff --git a/pubspec.yaml b/pubspec.yaml index 8461d7e1fd41a2722946f1aa14d522709d63e625..03e613c16785230cc16fab8a03ae15cc8e39c2fe 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,42 +17,7 @@ dev_dependencies: sdk: flutter mockito: 4.1.1 -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: plugin: androidPackage: com.idlefish.flutterboost pluginClass: FlutterBoostPlugin - - # To add assets to your plugin package, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # - # For details regarding assets in packages, see - # https://flutter.io/assets-and-images/#from-packages - # - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # To add custom fonts to your plugin package, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts in packages, see - # https://flutter.io/custom-fonts/#from-packages diff --git a/test/lib/unit/boost_channel_test.dart b/test/lib/unit/boost_channel_test.dart index c8feacf8d72970983e36f9b9239bc5368c579893..c6911bddfea88f537221cfca09baa8f436c96853 100644 --- a/test/lib/unit/boost_channel_test.dart +++ b/test/lib/unit/boost_channel_test.dart @@ -1,5 +1,6 @@ -import 'package:flutter_boost/channel/boost_channel.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_boost/channel/boost_channel.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { @@ -22,13 +23,12 @@ void main() { response = null; test('sendEvent successfully', () async { - Map msg1 = Map<dynamic,dynamic>(); - BoostChannel().sendEvent("name", msg1); - - Map msg = Map<dynamic,dynamic>(); - msg["name"] = "name"; - msg["arguments"] = msg1; + final Map<String, dynamic> msg1 = <String, dynamic>{}; + BoostChannel().sendEvent('name', msg1); + final Map<String, dynamic> msg = <String, dynamic>{}; + msg['name'] = 'name'; + msg['arguments'] = msg1; expect( log, @@ -36,13 +36,10 @@ void main() { ); }); - test('invokeMethod successfully', () async { - Map msg = <dynamic,dynamic>{}; - msg["test"] = "test"; - BoostChannel().invokeMethod<dynamic>("__event__1", msg); - -// expect(e, isException); + final Map<String, dynamic> msg = <String, dynamic>{}; + msg['test'] = 'test'; + BoostChannel().invokeMethod<dynamic>('__event__1', msg); expect( log, @@ -50,11 +47,10 @@ void main() { ); }); - test('invokeListMethod successfully', () async { - Map msg = <dynamic,dynamic>{}; - msg["test"] = "test"; - var bb = await BoostChannel().invokeListMethod<dynamic>("__event__1", msg); + final Map<String, dynamic> msg = <String, dynamic>{}; + msg['test'] = 'test'; + await BoostChannel().invokeListMethod<dynamic>('__event__1', msg); expect( log, @@ -62,11 +58,10 @@ void main() { ); }); - test('invokeMapMethod successfully', () async { - Map msg = <dynamic,dynamic>{}; - msg["test"] = "test"; - BoostChannel().invokeMapMethod<dynamic,dynamic>("__event__1", msg); + final Map<String, dynamic> msg = <String, dynamic>{}; + msg['test'] = 'test'; + BoostChannel().invokeMapMethod<dynamic, dynamic>('__event__1', msg); expect( log, @@ -75,9 +70,9 @@ void main() { }); test('invokeMapMethod successfully', () async { - Map msg = <dynamic,dynamic>{}; - msg["test"] = "test"; - BoostChannel().invokeMapMethod<dynamic,dynamic>("__event__1", msg); + final Map<String, dynamic> msg = <String, dynamic>{}; + msg['test'] = 'test'; + BoostChannel().invokeMapMethod<dynamic, dynamic>('__event__1', msg); expect( log, @@ -86,22 +81,24 @@ void main() { }); test('addEventListener successfully', () async { - Function test = BoostChannel().addEventListener( - "addEventListener", (String name, Map arguments) async => "test"); - print("xxx" + test.toString()); + final VoidCallback test = BoostChannel().addEventListener( + 'addEventListener', + (String name, Map<String, dynamic> arguments) async => 'test', + ); + print('xxx' + test.toString()); expect( test.toString(), - "Closure: () => Null", + 'Closure: () => Null', ); }); - test('addMethodHandler successfully', () async { - Function test = BoostChannel().addMethodHandler(( - MethodCall call) async => "test"); + final VoidCallback test = BoostChannel().addMethodHandler( + (MethodCall call) async => 'test', + ); expect( test.toString(), - "Closure: () => Null", + 'Closure: () => Null', ); }); }); diff --git a/test/lib/unit/boost_container_test.dart b/test/lib/unit/boost_container_test.dart index 07e47d2eeb5865eab0b88777d88c7b4d00000ebd..dd10d8224260d8546f85c6273e060dedcd9e1276 100644 --- a/test/lib/unit/boost_container_test.dart +++ b/test/lib/unit/boost_container_test.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -import 'package:flutter_boost/container/boost_container.dart'; +// import 'package:flutter_boost/container/boost_container.dart'; import 'package:flutter_test/flutter_test.dart'; class FirstWidget extends StatelessWidget { @@ -149,11 +149,11 @@ void main() { ); await tester.pumpWidget(widget); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); await tester.tap(find.byKey(targetKey)); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(exception, isInstanceOf<FlutterError>()); expect('$exception', diff --git a/test/lib/unit/boost_page_route_test.dart b/test/lib/unit/boost_page_route_test.dart index 1db8848691ee0a64386c78f112f26ba931120f09..4a3b2911cf1455e9de37b78939143dfe29e747d5 100644 --- a/test/lib/unit/boost_page_route_test.dart +++ b/test/lib/unit/boost_page_route_test.dart @@ -49,8 +49,8 @@ void main() { testWidgets( 'obtain BoostPageRoute through the BoostPageRoute.of(context) method', (WidgetTester tester) async { - dynamic boostPageRoute; - dynamic boostPageRouteFindByOfMethod; + BoostPageRoute<dynamic> boostPageRoute; + BoostPageRoute<dynamic> boostPageRouteFindByOfMethod; await tester.pumpWidget( MaterialApp( @@ -58,10 +58,11 @@ void main() { boostPageRoute = BoostPageRoute<void>( settings: settings, builder: (BuildContext context) => Builder( - builder: (context) { + builder: (BuildContext context) { return FloatingActionButton( onPressed: () { - boostPageRouteFindByOfMethod = BoostPageRoute.of<dynamic>(context); + boostPageRouteFindByOfMethod = + BoostPageRoute.of<dynamic>(context); }, ); }, @@ -74,7 +75,7 @@ void main() { await tester.tap(find.byType(FloatingActionButton)); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); // The route obtained from the ancestor node through the `of` method should be the same BoostPageRoute // as the originally created BoostPageRoute @@ -85,15 +86,15 @@ void main() { 'try to find BoostPageRoute through the BoostPageRoute.of(context) method, ' 'but it doesn\'t exist, the method should throw an Exception', (WidgetTester tester) async { - dynamic contextCache; + BuildContext contextCache; await tester.pumpWidget( MaterialApp( onGenerateRoute: (RouteSettings settings) { return MaterialPageRoute<dynamic>( settings: settings, - builder: (context) => Builder( - builder: (context) => FloatingActionButton( + builder: (BuildContext context) => Builder( + builder: (BuildContext context) => FloatingActionButton( onPressed: () { contextCache = context; }, @@ -104,7 +105,7 @@ void main() { ), ); await tester.tap(find.byType(FloatingActionButton)); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(() => BoostPageRoute.of<dynamic>(contextCache), throwsException); }); @@ -112,8 +113,8 @@ void main() { testWidgets( 'obtain BoostPageRoute through the BoostPageRoute.tryOf(context) method', (WidgetTester tester) async { - dynamic boostPageRoute; - dynamic boostPageRouteFindByOfMethod; + BoostPageRoute<dynamic> boostPageRoute; + BoostPageRoute<dynamic> boostPageRouteFindByOfMethod; await tester.pumpWidget( MaterialApp( @@ -121,7 +122,7 @@ void main() { boostPageRoute = BoostPageRoute<void>( settings: settings, builder: (BuildContext context) => Builder( - builder: (context) { + builder: (BuildContext context) { return FloatingActionButton( onPressed: () { boostPageRouteFindByOfMethod = @@ -137,7 +138,7 @@ void main() { ); await tester.tap(find.byType(FloatingActionButton)); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); // The route obtained from the ancestor node through the `tryOf` method should be the same BoostPageRoute // as the originally created BoostPageRoute @@ -149,7 +150,7 @@ void main() { 'try to find BoostPageRoute through the BoostPageRoute.tryOf(context) method, ' 'but it doesn\'t exist, the method should return null', (WidgetTester tester) async { - dynamic boostPageRouteFindByOfMethod; + BoostPageRoute<dynamic> boostPageRouteFindByOfMethod; await tester.pumpWidget( MaterialApp( @@ -157,7 +158,7 @@ void main() { return MaterialPageRoute<dynamic>( settings: settings, builder: (BuildContext context) => Builder( - builder: (context) { + builder: (BuildContext context) { return FloatingActionButton( onPressed: () { boostPageRouteFindByOfMethod = @@ -172,7 +173,7 @@ void main() { ); await tester.tap(find.byType(FloatingActionButton)); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(boostPageRouteFindByOfMethod, null); }); diff --git a/test/lib/unit/container_coordinator_test.dart b/test/lib/unit/container_coordinator_test.dart index 80e81616472ed1fea4f64b79b37bb8b0a1c1ce04..99ee05a16ddfa092e171b0b481d2e0065628174e 100644 --- a/test/lib/unit/container_coordinator_test.dart +++ b/test/lib/unit/container_coordinator_test.dart @@ -6,9 +6,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_boost/channel/boost_channel.dart'; import 'package:flutter_boost/container/container_coordinator.dart'; -import 'package:flutter_boost/flutter_boost.dart'; - -import 'dart:typed_data'; class MockBoostChannel extends BoostChannel implements Mock { MethodHandler get testHandler => _testHandler; @@ -17,40 +14,42 @@ class MockBoostChannel extends BoostChannel implements Mock { MethodHandler _testHandler; EventListener _testEventListener; + @override VoidCallback addEventListener(String name, EventListener listener) { _testEventListener = listener; return super.addEventListener(name, listener); } + @override VoidCallback addMethodHandler(MethodHandler handler) { _testHandler = handler; - return super.addMethodHandler(handler); + return super.addMethodHandler(handler); } } void main() { TestWidgetsFlutterBinding.ensureInitialized(); - const MessageCodec<dynamic> jsonMessage = JSONMessageCodec(); +// const MessageCodec<dynamic> jsonMessage = JSONMessageCodec(); test('test onMethodCall', () async { // Initialize all bindings because defaultBinaryMessenger.send() needs a window. TestWidgetsFlutterBinding.ensureInitialized(); - MockBoostChannel boostChannel = MockBoostChannel(); + final MockBoostChannel boostChannel = MockBoostChannel(); ContainerCoordinator(boostChannel); - final Map arguments =<dynamic,dynamic> {}; - arguments["pageName"] = "pageName"; - arguments["params"] = <dynamic,dynamic>{}; - arguments["uniqueId"] = "xxxxx"; + final Map<String, dynamic> arguments = <String, dynamic>{}; + arguments['pageName'] = 'pageName'; + arguments['params'] = <dynamic, dynamic>{}; + arguments['uniqueId'] = 'xxxxx'; - MethodCall call = MethodCall('didInitPageContainer', arguments); + final MethodCall call = MethodCall('didInitPageContainer', arguments); try { boostChannel.testHandler(call); } catch (e) { expect(e, isAssertionError); } - MethodCall call2 = MethodCall('willShowPageContainer', arguments); + final MethodCall call2 = MethodCall('willShowPageContainer', arguments); try { boostChannel.testHandler(call2); @@ -58,7 +57,7 @@ void main() { expect(e, isNoSuchMethodError); } - MethodCall call3 = MethodCall('didShowPageContainer', arguments); + final MethodCall call3 = MethodCall('didShowPageContainer', arguments); try { boostChannel.testHandler(call3); @@ -66,7 +65,8 @@ void main() { expect(e, isNoSuchMethodError); } - MethodCall call4 = MethodCall('willDisappearPageContainer', arguments); + final MethodCall call4 = + MethodCall('willDisappearPageContainer', arguments); try { boostChannel.testHandler(call4); @@ -74,7 +74,7 @@ void main() { expect(e, isNoSuchMethodError); } - MethodCall call5 = MethodCall('onNativePageResult', arguments); + final MethodCall call5 = MethodCall('onNativePageResult', arguments); try { boostChannel.testHandler(call5); @@ -82,14 +82,14 @@ void main() { expect(e, isNoSuchMethodError); } - MethodCall call6 = MethodCall('didDisappearPageContainer', arguments); + final MethodCall call6 = MethodCall('didDisappearPageContainer', arguments); try { boostChannel.testHandler(call6); } catch (e) { expect(e, isNoSuchMethodError); } - MethodCall call7 = MethodCall('willDeallocPageContainer', arguments); + final MethodCall call7 = MethodCall('willDeallocPageContainer', arguments); try { boostChannel.testHandler(call7); @@ -97,35 +97,36 @@ void main() { expect(e, isNoSuchMethodError); } - Map arg = <dynamic,dynamic>{'type': 'backPressedCallback'}; + final Map<String, dynamic> arg = <String, dynamic>{ + 'type': 'backPressedCallback' + }; try { - boostChannel.testEventListener("lifecycle", arg); + boostChannel.testEventListener('lifecycle', arg); } catch (e) { expect(e, isNoSuchMethodError); } - - - Map arg2 = <dynamic,dynamic>{'type': 'foreground'}; + final Map<String, dynamic> arg2 = <String, dynamic>{'type': 'foreground'}; try { - boostChannel.testEventListener("lifecycle", arg2); + boostChannel.testEventListener('lifecycle', arg2); } catch (e) { expect(e, isNoSuchMethodError); } - Map arg3 = <dynamic,dynamic>{'type': 'background'}; + final Map<String, dynamic> arg3 = <String, dynamic>{'type': 'background'}; try { - boostChannel.testEventListener("lifecycle", arg3); + boostChannel.testEventListener('lifecycle', arg3); } catch (e) { expect(e, isNoSuchMethodError); } - Map arg4 = <dynamic,dynamic>{'type': 'scheduleFrame'}; + final Map<String, dynamic> arg4 = <String, dynamic>{ + 'type': 'scheduleFrame' + }; try { - boostChannel.testEventListener("lifecycle", arg4); + boostChannel.testEventListener('lifecycle', arg4); } catch (e) { expect(e, isNoSuchMethodError); } }); - } diff --git a/test/lib/unit/container_manager_test.dart b/test/lib/unit/container_manager_test.dart index c78adf72c01f457a942eef8c465cec8d7cfc7b61..3ffec0158dc60fd8ef8e5f99676982a193d41352 100644 --- a/test/lib/unit/container_manager_test.dart +++ b/test/lib/unit/container_manager_test.dart @@ -12,19 +12,21 @@ class FirstRouteWidget extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('First Route'), + title: const Text('First Route'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ RaisedButton( - child: Text('First'), + child: const Text('First'), onPressed: () { - print("open second page!"); - FlutterBoost.singleton.open("second").then((Map value) { + print('open second page!'); + FlutterBoost.singleton + .open('second') + .then((Map<dynamic, dynamic> value) { print( - "call me when page is finished. did recieve second route result $value"); + 'call me when page is finished. did recieve second route result $value'); }); }, ), @@ -40,19 +42,21 @@ class SecondRouteWidget extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Second Route'), + title: const Text('Second Route'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ RaisedButton( - child: Text('Second'), + child: const Text('Second'), onPressed: () { - print("open second page!"); - FlutterBoost.singleton.open("second").then((Map value) { + print('open second page!'); + FlutterBoost.singleton + .open('second') + .then((Map<dynamic, dynamic> value) { print( - "call me when page is finished. did recieve second route result $value"); + 'call me when page is finished. did recieve second route result $value'); }); }, ), @@ -73,9 +77,11 @@ class _MyAppState extends State<MyApp> { void initState() { super.initState(); - FlutterBoost.singleton.registerPageBuilders({ - 'first': (pageName, params, _) => FirstRouteWidget(), - 'second': (pageName, params, _) => SecondRouteWidget(), + FlutterBoost.singleton.registerPageBuilders(<String, PageBuilder>{ + 'first': (String pageName, Map<String, dynamic> params, String _) => + FirstRouteWidget(), + 'second': (String pageName, Map<String, dynamic> params, String _) => + SecondRouteWidget(), }); } @@ -88,7 +94,7 @@ class _MyAppState extends State<MyApp> { assert(child is Navigator, 'child must be Navigator, what is wrong?'); final BoostContainerManager manager = BoostContainerManager( - initNavigator: child, + initNavigator: child as Navigator, ); return manager; @@ -113,19 +119,23 @@ void main() { testWidgets( 'through the `BoostContainerManager.of(context)` method', (WidgetTester tester) async { - var builderContext; - - FlutterBoost.singleton.registerPageBuilders({ - 'context': (pageName, params, _) => Builder( - builder: (context) { - return FloatingActionButton( - onPressed: () { - builderContext = context; - }, - ); - }, - ), - }); + BuildContext builderContext; + + FlutterBoost.singleton.registerPageBuilders( + <String, PageBuilder>{ + 'context': + (String pageName, Map<String, dynamic> params, String _) => + Builder( + builder: (BuildContext context) { + return FloatingActionButton( + onPressed: () { + builderContext = context; + }, + ); + }, + ), + }, + ); await tester.pumpWidget( MaterialApp( @@ -135,28 +145,34 @@ void main() { ); //open context page - ContainerCoordinator.singleton - .nativeContainerDidShow("context", {}, "1000000"); + ContainerCoordinator.singleton.nativeContainerDidShow( + 'context', + <String, dynamic>{}, + '1000000', + ); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(find.byType(FloatingActionButton), findsOneWidget); //get the context of the Builder await tester.tap(find.byType(FloatingActionButton)); - final isFind = BoostContainerManager.of(builderContext) != null; + final bool isFind = BoostContainerManager.of(builderContext) != null; - expect(isFind, true, - reason: '`BoostContainerManager.of` should be able to ' - 'find `ContainerManagerState` in `FlutterBoost.init()` based on the context of the `Builder`'); + expect( + isFind, + true, + reason: '`BoostContainerManager.of` should be able to ' + 'find `ContainerManagerState` in `FlutterBoost.init()` based on the context of the `Builder`', + ); }, ); // testWidgets( // 'through the `BoostContainerManager.of(context)` method', // (WidgetTester tester) async { -// var builderContext; +// BuildContext builderContext; // // await tester.pumpWidget( // MaterialApp( @@ -184,19 +200,22 @@ void main() { testWidgets( 'through the `BoostContainerManager.tryOf(context)` method', (WidgetTester tester) async { - var builderContext; - - FlutterBoost.singleton.registerPageBuilders({ - 'context': (pageName, params, _) => Builder( - builder: (context) { - return FloatingActionButton( - onPressed: () { - builderContext = context; - }, - ); - }, - ), - }); + BuildContext builderContext; + + FlutterBoost.singleton.registerPageBuilders( + <String, PageBuilder>{ + 'context': (String pageName, Map<String, dynamic> params, _) => + Builder( + builder: (BuildContext context) { + return FloatingActionButton( + onPressed: () { + builderContext = context; + }, + ); + }, + ), + }, + ); await tester.pumpWidget( MaterialApp( @@ -206,21 +225,25 @@ void main() { ); //open context page - ContainerCoordinator.singleton - .nativeContainerDidShow("context", {}, "1000000"); + ContainerCoordinator.singleton.nativeContainerDidShow( + 'context', <String, dynamic>{}, '1000000'); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(find.byType(FloatingActionButton), findsOneWidget); //get the context of the Builder await tester.tap(find.byType(FloatingActionButton)); - final isFind = BoostContainerManager.tryOf(builderContext) != null; + final bool isFind = + BoostContainerManager.tryOf(builderContext) != null; - expect(isFind, true, - reason: '`BoostContainerManager.tryOf` should be able to ' - 'find `ContainerManagerState` in `FlutterBoost.init()` based on the context of the `Builder`'); + expect( + isFind, + true, + reason: '`BoostContainerManager.tryOf` should be able to ' + 'find `ContainerManagerState` in `FlutterBoost.init()` based on the context of the `Builder`', + ); }, ); }, @@ -230,19 +253,22 @@ void main() { testWidgets( 'containerCounts should change based on the number of pages', (WidgetTester tester) async { - var builderContext; - - FlutterBoost.singleton.registerPageBuilders({ - 'context': (pageName, params, _) => Builder( - builder: (context) { - return FloatingActionButton( - onPressed: () { - builderContext = context; - }, - ); - }, - ), - }); + BuildContext builderContext; + + FlutterBoost.singleton.registerPageBuilders( + <String, PageBuilder>{ + 'context': (String pageName, Map<String, dynamic> params, _) => + Builder( + builder: (BuildContext context) { + return FloatingActionButton( + onPressed: () { + builderContext = context; + }, + ); + }, + ), + }, + ); await tester.pumpWidget( MaterialApp( @@ -253,23 +279,24 @@ void main() { //open first context page ContainerCoordinator.singleton - .nativeContainerDidShow("context", {}, "1000000"); + .nativeContainerDidShow('context', <String, dynamic>{}, '1000000'); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); //get the context of the Builder await tester.tap(find.byType(FloatingActionButton)); - final containerManagerState = BoostContainerManager.of(builderContext); + final ContainerManagerState containerManagerState = + BoostContainerManager.of(builderContext); expect(containerManagerState.containerCounts, 1, reason: '1 page shown'); //open second context page ContainerCoordinator.singleton - .nativeContainerDidShow("context", {}, "2000000"); + .nativeContainerDidShow('context', <String, dynamic>{}, '2000000'); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(containerManagerState.containerCounts, 2, reason: '2 page shown'); @@ -277,7 +304,7 @@ void main() { //pop second context page containerManagerState.pop(); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(containerManagerState.containerCounts, 1, reason: 'second context page closed, Only one page left'); @@ -285,7 +312,7 @@ void main() { //pop last context page containerManagerState.pop(); - await tester.pump(Duration(seconds: 1)); + await tester.pump(const Duration(seconds: 1)); expect(containerManagerState.containerCounts, 0, reason: 'last context page closed, no page left'); diff --git a/test/lib/unit/flutter_boost_test.dart b/test/lib/unit/flutter_boost_test.dart index 3144faa34c41df602aba7069ae38c329091cdaaf..7bff4c0727879fcad69c86c75437c0c54476f042 100644 --- a/test/lib/unit/flutter_boost_test.dart +++ b/test/lib/unit/flutter_boost_test.dart @@ -1,44 +1,52 @@ -import 'package:flutter_boost/container/container_manager.dart'; - import 'package:flutter/widgets.dart'; import 'package:flutter_boost/flutter_boost.dart'; +import 'package:flutter_boost/container/container_manager.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); + test('test onMethodCall', () async { + FlutterBoost.singleton.registerDefaultPageBuilder( + (String pageName, Map<String, dynamic> params, String _) => + Container()); + FlutterBoost.singleton.addContainerObserver( + (ContainerOperation operation, BoostContainerSettings settings) {}, + ); + + FlutterBoost.singleton.addBoostContainerLifeCycleObserver( + (ContainerLifeCycle state, BoostContainerSettings settings) {}, + ); + + FlutterBoost.singleton.addBoostNavigatorObserver(NavigatorObserver()); + + try { + FlutterBoost.singleton.open('url'); + } catch (e) { + expect(e, isException); + } + try { + FlutterBoost.singleton.close('url'); + } catch (e) { + expect(e, isNoSuchMethodError); + } + try { + FlutterBoost.singleton.closeCurrent( + result: <String, dynamic>{}, + exts: <String, dynamic>{}, + ); + } catch (e) { + expect(e, isNoSuchMethodError); + } -// test('test onMethodCall', () async { -// FlutterBoost.singleton -// .registerDefaultPageBuilder((pageName, params, _) => Container()); -// FlutterBoost.singleton.addContainerObserver( -// (ContainerOperation operation, BoostContainerSettings settings) {}); -// -// FlutterBoost.singleton.addBoostContainerLifeCycleObserver( -// (ContainerLifeCycle state, BoostContainerSettings settings) {}); -// -// FlutterBoost.singleton.addBoostNavigatorObserver(NavigatorObserver()); -// -// try { -// FlutterBoost.singleton.open("url"); -// } catch (e) { -// expect(e, isException); -// } -// try { -// FlutterBoost.singleton.close("url"); -// } catch (e) { -// expect(e, isNoSuchMethodError); -// } -// try { -// FlutterBoost.singleton.closeCurrent(result: <String,dynamic>{}, exts: <String,dynamic>{}); -// } catch (e) { -// expect(e, isNoSuchMethodError); -// } -// -// try { -// FlutterBoost.singleton.closeByContext(null, result: <String,dynamic>{}, exts: <String,dynamic>{}); -// } catch (e) { -// expect(e, isNoSuchMethodError); -// } -// }); + try { + FlutterBoost.singleton.closeByContext( + null, + result: <String, dynamic>{}, + exts: <String, dynamic>{}, + ); + } catch (e) { + expect(e, isNoSuchMethodError); + } + }); } diff --git a/test/lib/unit/page_widget_test.dart b/test/lib/unit/page_widget_test.dart index fba52ada80ccb631a1d7b4af933e02b4d04ccda0..00faaf92f03417514bb62d9cb824ab12eaf1b0ec 100644 --- a/test/lib/unit/page_widget_test.dart +++ b/test/lib/unit/page_widget_test.dart @@ -1,9 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_boost/flutter_boost.dart'; +import 'package:flutter_boost/container/container_coordinator.dart'; import 'package:flutter_test/flutter_test.dart'; + import 'page_widgets.dart'; -import 'package:flutter_boost/container/container_coordinator.dart'; class MyApp extends StatefulWidget { @override @@ -15,14 +16,19 @@ class _MyAppState extends State<MyApp> { void initState() { super.initState(); - FlutterBoost.singleton.registerPageBuilders({ - 'embeded': (pageName, params, _) => EmbededFirstRouteWidget(), - 'first': (pageName, params, _) => FirstRouteWidget(), - 'second': (pageName, params, _) => SecondRouteWidget(), - 'tab': (pageName, params, _) => TabRouteWidget(), - 'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params), - 'flutterPage': (pageName, params, _) { - print("flutterPage params:$params"); + FlutterBoost.singleton.registerPageBuilders(<String, PageBuilder>{ + 'embeded': (String pageName, Map<String, dynamic> params, _) => + EmbededFirstRouteWidget(), + 'first': (String pageName, Map<String, dynamic> params, _) => + FirstRouteWidget(), + 'second': (String pageName, Map<String, dynamic> params, _) => + SecondRouteWidget(), + 'tab': (String pageName, Map<String, dynamic> params, _) => + TabRouteWidget(), + 'flutterFragment': (String pageName, Map<String, dynamic> params, _) => + FragmentRouteWidget(params), + 'flutterPage': (String pageName, Map<String, dynamic> params, _) { + print('flutterPage params:$params'); return FlutterRouteWidget(params: params); }, @@ -40,24 +46,33 @@ class _MyAppState extends State<MyApp> { } void _onRoutePushed( - String pageName, String uniqueId, Map params, Route route, Future _) {} + String pageName, + String uniqueId, + Map<String, dynamic> params, + Route<dynamic> route, + Future<dynamic> _, + ) {} } class TestBoostNavigatorObserver extends NavigatorObserver { + @override void didPush(Route<dynamic> route, Route<dynamic> previousRoute) { - print("flutterboost#didPush"); + print('flutterboost#didPush'); } + @override void didPop(Route<dynamic> route, Route<dynamic> previousRoute) { - print("flutterboost#didPop"); + print('flutterboost#didPop'); } + @override void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) { - print("flutterboost#didRemove"); + print('flutterboost#didRemove'); } + @override void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) { - print("flutterboost#didReplace"); + print('flutterboost#didReplace'); } } @@ -72,7 +87,7 @@ void main() { ); //open firt page ContainerCoordinator.singleton - .nativeContainerDidShow("first", <dynamic,dynamic>{}, "1000000"); + .nativeContainerDidShow('first', <String, dynamic>{}, '1000000'); await tester.pump(const Duration(seconds: 1)); @@ -80,7 +95,7 @@ void main() { //open second page firt(1000000)->second(2000000) ContainerCoordinator.singleton - .nativeContainerDidShow("second", <dynamic,dynamic>{}, "2000000"); + .nativeContainerDidShow('second', <String, dynamic>{}, '2000000'); await tester.pump(const Duration(seconds: 1)); @@ -89,7 +104,7 @@ void main() { await tester.pump(const Duration(seconds: 1)); //close sencod page firt(1000000) - FlutterBoost.containerManager?.remove("2000000"); + FlutterBoost.containerManager?.remove('2000000'); await tester.pump(const Duration(seconds: 1)); @@ -97,7 +112,7 @@ void main() { // second page ,but pageId is 2000001 firt(1000000)->second(2000001) ContainerCoordinator.singleton - .nativeContainerDidShow("second", <dynamic,dynamic>{}, "2000001"); + .nativeContainerDidShow('second', <String, dynamic>{}, '2000001'); await tester.pump(const Duration(seconds: 1)); @@ -107,7 +122,7 @@ void main() { //reopen firt page second(2000001)->firt(1000000) ContainerCoordinator.singleton - .nativeContainerDidShow("first",<dynamic,dynamic> {}, "1000000"); + .nativeContainerDidShow('first', <String, dynamic>{}, '1000000'); await tester.pump(const Duration(seconds: 1)); @@ -117,7 +132,7 @@ void main() { // reopen second page and pageId is 2000001 firt(1000000)->second(2000001) ContainerCoordinator.singleton - .nativeContainerDidShow("second", <dynamic,dynamic>{}, "2000001"); + .nativeContainerDidShow('second', <String, dynamic>{}, '2000001'); await tester.pump(const Duration(seconds: 1)); @@ -126,24 +141,18 @@ void main() { await tester.pump(const Duration(seconds: 1)); //close firt(1000000) page second(2000001) - FlutterBoost.containerManager?.remove("1000000"); + FlutterBoost.containerManager?.remove('1000000'); await tester.pump(const Duration(seconds: 1)); expect(find.text('Second'), findsOneWidget); - // open second(2000003) ContainerCoordinator.singleton - .nativeContainerDidShow("second", <dynamic,dynamic>{}, "2000003"); + .nativeContainerDidShow('second', <String, dynamic>{}, '2000003'); await tester.idle(); expect(find.text('Second'), findsOneWidget); - - - - - }); } diff --git a/test/lib/unit/page_widgets.dart b/test/lib/unit/page_widgets.dart index ac28940adccb24d20f0a2b23f52313f45e9bf4cc..ba0ef372518cb190ca0440cfca2aae90054c7569 100755 --- a/test/lib/unit/page_widgets.dart +++ b/test/lib/unit/page_widgets.dart @@ -7,36 +7,38 @@ class FirstRouteWidget extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('First Route'), + title: const Text('First Route'), ), body: Center( - child: - Column( + child: Column( mainAxisAlignment: MainAxisAlignment.center, - children: - <Widget>[ + children: <Widget>[ RaisedButton( - child: Text('First'), - 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"); - }); - }, - ), - - RaisedButton( - child: Text('Present second route'), - onPressed: () { - print("Present second page!"); - FlutterBoost.singleton.open("second",urlParams:<dynamic,dynamic>{"present":true}).then((Map value) { - print( - "call me when page is finished. did recieve second route result $value"); - }); - }, - ), - ], + child: const Text('First'), + onPressed: () { + print('open second page!'); + FlutterBoost.singleton + .open('second') + .then((Map<dynamic, dynamic> value) { + print( + 'call me when page is finished. did recieve second route result $value'); + }); + }, + ), + RaisedButton( + child: const Text('Present second route'), + onPressed: () { + print('Present second page!'); + FlutterBoost.singleton.open('second', + urlParams: <String, dynamic>{ + 'present': true + }).then((Map<dynamic, dynamic> value) { + print( + 'call me when page is finished. did recieve second route result $value'); + }); + }, + ), + ], ), ), ); @@ -49,12 +51,14 @@ class EmbededFirstRouteWidget extends StatelessWidget { return Scaffold( body: Center( child: RaisedButton( - child: Text('Open second route'), + child: const Text('Open second route'), onPressed: () { - print("open second page!"); - FlutterBoost.singleton.open("second").then((Map value) { + print('open second page!'); + FlutterBoost.singleton + .open('second') + .then((Map<dynamic, dynamic> value) { print( - "call me when page is finished. did recieve second route result $value"); + 'call me when page is finished. did recieve second route result $value'); }); }, ), @@ -68,19 +72,19 @@ class SecondRouteWidget extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text("Second"), + title: const Text('Second'), ), body: Center( child: RaisedButton( onPressed: () { // Navigate back to first route when tapped. - BoostContainerSettings settings = + final BoostContainerSettings settings = BoostContainer.of(context).settings; FlutterBoost.singleton.close(settings.uniqueId, - result:<dynamic,dynamic>{"result": "data from second"}); + result: <String, dynamic>{'result': 'data from second'}); }, - child: Text('Go back with result!'), + child: const Text('Go back with result!'), ), ), ); @@ -92,14 +96,14 @@ class TabRouteWidget extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text("Tab Route"), + title: const Text('Tab Route'), ), body: Center( child: RaisedButton( onPressed: () { - FlutterBoost.singleton.open("second"); + FlutterBoost.singleton.open('second'); }, - child: Text('Open second route'), + child: const Text('Open second route'), ), ), ); @@ -107,8 +111,9 @@ class TabRouteWidget extends StatelessWidget { } class FlutterRouteWidget extends StatefulWidget { - FlutterRouteWidget({this.params,this.message}); - final Map params; + const FlutterRouteWidget({this.params, this.message}); + + final Map<String, dynamic> params; final String message; @override @@ -116,176 +121,190 @@ class FlutterRouteWidget extends StatefulWidget { } class _FlutterRouteWidgetState extends State<FlutterRouteWidget> { - final TextEditingController _usernameController = TextEditingController(); - @override Widget build(BuildContext context) { - final String message=widget.message; + final String message = widget.message; return Scaffold( appBar: AppBar( - brightness:Brightness.light, + brightness: Brightness.light, backgroundColor: Colors.white, - textTheme:new TextTheme(title: TextStyle(color: Colors.black)) , - - title: Text('flutter_boost_example'), + textTheme: TextTheme(title: TextStyle(color: Colors.black)), + title: const Text('flutter_boost_example'), ), body: SingleChildScrollView( - child:Container( - margin: const EdgeInsets.all(24.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: <Widget>[ - Container( - margin: const EdgeInsets.only(top: 10.0,bottom: 20.0), - child: Text( - message ?? "This is a flutter activity \n params:${widget.params}", - style: TextStyle(fontSize: 28.0, color: Colors.blue), - ), - alignment: AlignmentDirectional.center, + child: Container( + margin: const EdgeInsets.all(24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: <Widget>[ + Container( + margin: const EdgeInsets.only(top: 10.0, bottom: 20.0), + child: Text( + message ?? + 'This is a flutter activity \n params:${widget.params}', + style: TextStyle(fontSize: 28.0, color: Colors.blue), ), -// Expanded(child: Container()), - const CupertinoTextField( - prefix: Icon( - CupertinoIcons.person_solid, - color: CupertinoColors.lightBackgroundGray, - size: 28.0, + alignment: AlignmentDirectional.center, + ), + const CupertinoTextField( + prefix: Icon( + CupertinoIcons.person_solid, + color: CupertinoColors.lightBackgroundGray, + size: 28.0, + ), + padding: EdgeInsets.symmetric(horizontal: 6.0, vertical: 12.0), + clearButtonMode: OverlayVisibilityMode.editing, + textCapitalization: TextCapitalization.words, + autocorrect: false, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + width: 0.0, color: CupertinoColors.inactiveGray), ), - padding: EdgeInsets.symmetric(horizontal: 6.0, vertical: 12.0), - clearButtonMode: OverlayVisibilityMode.editing, - textCapitalization: TextCapitalization.words, - autocorrect: false, - decoration: BoxDecoration( - border: Border(bottom: BorderSide(width: 0.0, color: CupertinoColors.inactiveGray)), + ), + placeholder: 'Name', + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: Text( + 'open native page', + style: TextStyle(fontSize: 22.0, color: Colors.black), ), - placeholder: 'Name', ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open native page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 - ///例如:sample://nativePage?aaa=bbb - onTap: () => FlutterBoost.singleton - .open("sample://nativePage", urlParams: <dynamic,dynamic>{ - "query": {"aaa": "bbb"} - }), + ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 + ///例如:sample://nativePage?aaa=bbb + onTap: () => FlutterBoost.singleton.open( + 'sample://nativePage', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'}, + }, ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open first', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - - ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 - ///例如:sample://nativePage?aaa=bbb - onTap: () => FlutterBoost.singleton - .open("first", urlParams: <dynamic,dynamic>{ - "query": {"aaa": "bbb"} - }), + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: Text( + 'open first', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open second', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 - ///例如:sample://nativePage?aaa=bbb - onTap: () => FlutterBoost.singleton - .open("second", urlParams: <dynamic,dynamic>{ - "query": {"aaa": "bbb"} - }), + ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 + ///例如:sample://nativePage?aaa=bbb + onTap: () => FlutterBoost.singleton.open( + 'first', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'}, + }, ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open tab', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - - ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 - ///例如:sample://nativePage?aaa=bbb - onTap: () => FlutterBoost.singleton - .open("tab", urlParams: <dynamic,dynamic>{ - "query": {"aaa": "bbb"} - }), + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: Text( + 'open second', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open flutter page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 - ///例如:sample://nativePage?aaa=bbb - onTap: () => FlutterBoost.singleton - .open("sample://flutterPage", urlParams:<dynamic,dynamic> { - "query": {"aaa": "bbb"} - }), + ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 + ///例如:sample://nativePage?aaa=bbb + onTap: () => FlutterBoost.singleton.open( + 'second', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'}, + }, + ), + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: Text( + 'open tab', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'push flutter widget', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - onTap: () { - Navigator.push<dynamic>(context, - MaterialPageRoute<dynamic>(builder: (_) => PushWidget())); + + ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 + ///例如:sample://nativePage?aaa=bbb + onTap: () => FlutterBoost.singleton.open( + 'tab', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'} }, ), + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: Text( + 'open flutter page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + ), + ), + ///åŽé¢çš„傿•°ä¼šåœ¨nativeçš„IPlatform.startActivityæ–¹æ³•å›žè°ƒä¸æ‹¼æŽ¥åˆ°urlçš„query部分。 + ///例如:sample://nativePage?aaa=bbb + onTap: () => FlutterBoost.singleton.open( + 'sample://flutterPage', + urlParams: <String, dynamic>{ + 'query': <String, dynamic>{'aaa': 'bbb'} + }, + ), + ), InkWell( child: Container( padding: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0), color: Colors.yellow, child: Text( - 'push Platform demo', + 'push flutter widget', style: TextStyle(fontSize: 22.0, color: Colors.black), )), onTap: () { + Navigator.push<dynamic>( + context, + MaterialPageRoute<dynamic>(builder: (_) => PushWidget()), + ); }, ), - InkWell( - child: Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - color: Colors.yellow, - child: Text( - 'open flutter fragment page', - style: TextStyle(fontSize: 22.0, color: Colors.black), - )), - onTap: () => FlutterBoost.singleton - .open("sample://flutterFragmentPage"), - ), - ], - ), - + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: Text( + 'push Platform demo', + style: TextStyle(fontSize: 22.0, color: Colors.black), + )), + onTap: () {}, + ), + InkWell( + child: Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + color: Colors.yellow, + child: Text( + 'open flutter fragment page', + style: TextStyle(fontSize: 22.0, color: Colors.black), + )), + onTap: () => + FlutterBoost.singleton.open('sample://flutterFragmentPage'), + ), + ], + ), ), ), ); @@ -293,15 +312,15 @@ class _FlutterRouteWidgetState extends State<FlutterRouteWidget> { } class FragmentRouteWidget extends StatelessWidget { - final Map params; + const FragmentRouteWidget(this.params); - FragmentRouteWidget(this.params); + final Map<String, dynamic> params; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('flutter_boost_example'), + title: const Text('flutter_boost_example'), ), body: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -309,7 +328,7 @@ class FragmentRouteWidget extends StatelessWidget { Container( margin: const EdgeInsets.only(top: 80.0), child: Text( - "This is a flutter fragment", + 'This is a flutter fragment', style: TextStyle(fontSize: 28.0, color: Colors.blue), ), alignment: AlignmentDirectional.center, @@ -317,7 +336,7 @@ class FragmentRouteWidget extends StatelessWidget { Container( margin: const EdgeInsets.only(top: 32.0), child: Text( - params['tag'] ?? '', + '${params['tag']}' ?? '', style: TextStyle(fontSize: 28.0, color: Colors.red), ), alignment: AlignmentDirectional.center, @@ -332,7 +351,7 @@ class FragmentRouteWidget extends StatelessWidget { 'open native page', style: TextStyle(fontSize: 22.0, color: Colors.black), )), - onTap: () => FlutterBoost.singleton.open("sample://nativePage"), + onTap: () => FlutterBoost.singleton.open('sample://nativePage'), ), InkWell( child: Container( @@ -343,7 +362,7 @@ class FragmentRouteWidget extends StatelessWidget { 'open flutter page', style: TextStyle(fontSize: 22.0, color: Colors.black), )), - onTap: () => FlutterBoost.singleton.open("sample://flutterPage"), + onTap: () => FlutterBoost.singleton.open('sample://flutterPage'), ), InkWell( child: Container( @@ -355,7 +374,7 @@ class FragmentRouteWidget extends StatelessWidget { style: TextStyle(fontSize: 22.0, color: Colors.black), )), onTap: () => - FlutterBoost.singleton.open("sample://flutterFragmentPage"), + FlutterBoost.singleton.open('sample://flutterFragmentPage'), ) ], ), @@ -373,13 +392,13 @@ class _PushWidgetState extends State<PushWidget> { @override void initState() { - // TODO: implement initState + // TODO(unknown): implement initState super.initState(); } @override void didChangeDependencies() { - // TODO: implement didChangeDependencies + // TODO(unknown): implement didChangeDependencies super.didChangeDependencies(); // if (_backPressedListenerUnsub == null) { @@ -395,13 +414,13 @@ class _PushWidgetState extends State<PushWidget> { @override void dispose() { - // TODO: implement dispose + // TODO(unknown): implement dispose super.dispose(); _backPressedListenerUnsub?.call(); } @override Widget build(BuildContext context) { - return FlutterRouteWidget(message: "Pushed Widget"); + return const FlutterRouteWidget(message: 'Pushed Widget'); } }