Commit 9fb145a1 authored by nightfallsad's avatar nightfallsad Committed by GitHub

Merge pull request #7 from alibaba/master

merge code
parents 16f497e9 db7ca34a
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
analyzer: analyzer:
strong-mode: strong-mode:
implicit-casts: false
implicit-dynamic: false implicit-dynamic: false
errors: errors:
# treat missing required parameters as a warning (not a hint) # treat missing required parameters as a warning (not a hint)
...@@ -38,9 +39,7 @@ analyzer: ...@@ -38,9 +39,7 @@ analyzer:
# see https://github.com/dart-lang/sdk/issues/28463 # see https://github.com/dart-lang/sdk/issues/28463
- "lib/i18n/messages_*.dart" - "lib/i18n/messages_*.dart"
- "lib/src/http/**" - "lib/src/http/**"
- "example/**"
- "example_swift/**"
- "test/**"
linter: linter:
rules: rules:
# these rules are documented on and in the same order as # these rules are documented on and in the same order as
...@@ -60,6 +59,7 @@ linter: ...@@ -60,6 +59,7 @@ linter:
- avoid_classes_with_only_static_members - avoid_classes_with_only_static_members
# - avoid_double_and_int_checks # only useful when targeting JS runtime # - avoid_double_and_int_checks # only useful when targeting JS runtime
- avoid_empty_else - avoid_empty_else
- avoid_equals_and_hash_code_on_mutable_classes
- avoid_field_initializers_in_const_classes - avoid_field_initializers_in_const_classes
- avoid_function_literals_in_foreach_calls - avoid_function_literals_in_foreach_calls
# - avoid_implementing_value_types # not yet tested # - avoid_implementing_value_types # not yet tested
...@@ -67,7 +67,9 @@ linter: ...@@ -67,7 +67,9 @@ linter:
# - avoid_js_rounded_ints # only useful when targeting JS runtime # - avoid_js_rounded_ints # only useful when targeting JS runtime
- avoid_null_checks_in_equality_operators - avoid_null_checks_in_equality_operators
# - avoid_positional_boolean_parameters # not yet tested # - 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_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_relative_lib_imports
- avoid_renaming_method_parameters - avoid_renaming_method_parameters
- avoid_return_types_on_setters - avoid_return_types_on_setters
...@@ -77,13 +79,16 @@ linter: ...@@ -77,13 +79,16 @@ linter:
# - avoid_returning_this # there are plenty of valid reasons to return this # - avoid_returning_this # there are plenty of valid reasons to return this
# - avoid_setters_without_getters # not yet tested # - avoid_setters_without_getters # not yet tested
# - avoid_shadowing_type_parameters # 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_slow_async_io
- avoid_types_as_parameter_names - avoid_types_as_parameter_names
# - avoid_types_on_closure_parameters # conflicts with always_specify_types # - avoid_types_on_closure_parameters # conflicts with always_specify_types
# - avoid_unnecessary_containers # not yet tested
- avoid_unused_constructor_parameters - avoid_unused_constructor_parameters
- avoid_void_async - avoid_void_async
# - avoid_web_libraries_in_flutter # not yet tested
- await_only_futures - await_only_futures
- camel_case_extensions
- camel_case_types - camel_case_types
- cancel_subscriptions - cancel_subscriptions
# - cascade_invocations # not yet tested # - cascade_invocations # not yet tested
...@@ -109,8 +114,11 @@ linter: ...@@ -109,8 +114,11 @@ linter:
# - lines_longer_than_80_chars # not yet tested # - lines_longer_than_80_chars # not yet tested
- list_remove_unrelated_type - list_remove_unrelated_type
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 # - 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_adjacent_strings_in_list
- no_duplicate_case_values - no_duplicate_case_values
# - no_logic_in_create_state # not yet tested
# - no_runtimeType_toString # not yet tested
- non_constant_identifier_names - non_constant_identifier_names
# - null_closures # not yet tested # - null_closures # not yet tested
# - omit_local_variable_types # opposite of always_specify_types # - omit_local_variable_types # opposite of always_specify_types
...@@ -136,9 +144,9 @@ linter: ...@@ -136,9 +144,9 @@ linter:
- prefer_equal_for_default_values - 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_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_fields
# - prefer_final_in_for_each # not yet tested - prefer_final_in_for_each
- prefer_final_locals - prefer_final_locals
# - prefer_for_elements_to_map_fromIterable # not yet tested - prefer_for_elements_to_map_fromIterable
- prefer_foreach - prefer_foreach
# - prefer_function_declarations_over_variables # not yet tested # - prefer_function_declarations_over_variables # not yet tested
- prefer_generic_function_type_aliases - prefer_generic_function_type_aliases
...@@ -150,9 +158,11 @@ linter: ...@@ -150,9 +158,11 @@ linter:
# - prefer_interpolation_to_compose_strings # not yet tested # - prefer_interpolation_to_compose_strings # not yet tested
- prefer_is_empty - prefer_is_empty
- prefer_is_not_empty - prefer_is_not_empty
- prefer_is_not_operator
- prefer_iterable_whereType - prefer_iterable_whereType
# - prefer_mixin # https://github.com/dart-lang/language/issues/32 # - 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_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_single_quotes
- prefer_spread_collections - prefer_spread_collections
- prefer_typing_uninitialized_variables - prefer_typing_uninitialized_variables
...@@ -173,6 +183,7 @@ linter: ...@@ -173,6 +183,7 @@ linter:
# - unnecessary_await_in_return # not yet tested # - unnecessary_await_in_return # not yet tested
- unnecessary_brace_in_string_interps - unnecessary_brace_in_string_interps
- unnecessary_const - unnecessary_const
# - unnecessary_final # conflicts with prefer_final_locals
- unnecessary_getters_setters - unnecessary_getters_setters
# - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
- unnecessary_new - unnecessary_new
...@@ -181,14 +192,16 @@ linter: ...@@ -181,14 +192,16 @@ linter:
- unnecessary_overrides - unnecessary_overrides
- unnecessary_parenthesis - unnecessary_parenthesis
- unnecessary_statements - unnecessary_statements
# - unnecessary_string_interpolations
- unnecessary_this - unnecessary_this
- unrelated_type_equality_checks - unrelated_type_equality_checks
# - unsafe_html # not yet tested # - unsafe_html # not yet tested
- use_full_hex_values_for_flutter_colors - use_full_hex_values_for_flutter_colors
# - use_function_type_syntax_for_parameters # not yet tested # - use_function_type_syntax_for_parameters # not yet tested
# - use_key_in_widget_constructors # not yet tested
- use_rethrow_when_possible - use_rethrow_when_possible
# - use_setters_to_change_properties # not yet tested # - use_setters_to_change_properties # not yet tested
# - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 # - 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 # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
- valid_regexps - valid_regexps
# - void_checks # not yet tested - void_checks
\ No newline at end of file
...@@ -22,7 +22,7 @@ rootProject.allprojects { ...@@ -22,7 +22,7 @@ rootProject.allprojects {
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
android { android {
compileSdkVersion 28 compileSdkVersion 29
buildToolsVersion '28.0.3' buildToolsVersion '28.0.3'
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
......
...@@ -21,6 +21,7 @@ import android.view.*; ...@@ -21,6 +21,7 @@ import android.view.*;
import android.widget.*; import android.widget.*;
import com.idlefish.flutterboost.FlutterBoost; import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.XFlutterView; import com.idlefish.flutterboost.XFlutterView;
import com.idlefish.flutterboost.XPlatformPlugin;
import io.flutter.Log; import io.flutter.Log;
import io.flutter.embedding.android.DrawableSplashScreen; import io.flutter.embedding.android.DrawableSplashScreen;
import io.flutter.embedding.android.FlutterView; import io.flutter.embedding.android.FlutterView;
...@@ -439,12 +440,8 @@ public class BoostFlutterActivity extends Activity ...@@ -439,12 +440,8 @@ public class BoostFlutterActivity extends Activity
@Nullable @Nullable
@Override @Override
public PlatformPlugin providePlatformPlugin(@Nullable Activity activity, @NonNull FlutterEngine flutterEngine) { public XPlatformPlugin providePlatformPlugin( @NonNull FlutterEngine flutterEngine) {
if (activity != null) { return new XPlatformPlugin( flutterEngine.getPlatformChannel());
return new PlatformPlugin(getActivity(), flutterEngine.getPlatformChannel());
} else {
return null;
}
} }
/** /**
......
...@@ -23,6 +23,7 @@ import java.util.Map; ...@@ -23,6 +23,7 @@ import java.util.Map;
import com.idlefish.flutterboost.FlutterBoost; import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.Utils; import com.idlefish.flutterboost.Utils;
import com.idlefish.flutterboost.XFlutterView; import com.idlefish.flutterboost.XFlutterView;
import com.idlefish.flutterboost.XPlatformPlugin;
import com.idlefish.flutterboost.interfaces.IFlutterViewContainer; import com.idlefish.flutterboost.interfaces.IFlutterViewContainer;
import com.idlefish.flutterboost.interfaces.IOperateSyncer; import com.idlefish.flutterboost.interfaces.IOperateSyncer;
import io.flutter.Log; import io.flutter.Log;
...@@ -30,6 +31,7 @@ import io.flutter.app.FlutterActivity; ...@@ -30,6 +31,7 @@ import io.flutter.app.FlutterActivity;
import io.flutter.embedding.android.*; import io.flutter.embedding.android.*;
import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterShellArgs; import io.flutter.embedding.engine.FlutterShellArgs;
import io.flutter.embedding.engine.plugins.activity.ActivityControlSurface;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.platform.PlatformPlugin; import io.flutter.plugin.platform.PlatformPlugin;
...@@ -39,7 +41,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -39,7 +41,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
private static final String TAG = "FlutterActivityAndFragmentDelegate"; private static final String TAG = "FlutterActivityAndFragmentDelegate";
private static int ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE=0;
@NonNull @NonNull
private Host host; private Host host;
@Nullable @Nullable
...@@ -49,7 +51,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -49,7 +51,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
@Nullable @Nullable
private XFlutterView flutterView; private XFlutterView flutterView;
@Nullable @Nullable
private PlatformPlugin platformPlugin; private XPlatformPlugin platformPlugin;
private boolean isFlutterEngineFromHost; private boolean isFlutterEngineFromHost;
...@@ -95,7 +97,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -95,7 +97,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
// TODO(mattcarroll): the PlatformPlugin needs to be reimagined because it implicitly takes // TODO(mattcarroll): the PlatformPlugin needs to be reimagined because it implicitly takes
// control of the entire window. This is unacceptable for non-fullscreen // control of the entire window. This is unacceptable for non-fullscreen
// use-cases. // use-cases.
platformPlugin = host.providePlatformPlugin(host.getActivity(), flutterEngine); platformPlugin = host.providePlatformPlugin(flutterEngine);
host.configureFlutterEngine(flutterEngine); host.configureFlutterEngine(flutterEngine);
...@@ -129,13 +131,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -129,13 +131,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
Log.v(TAG, "Creating FlutterView."); Log.v(TAG, "Creating FlutterView.");
flutterEngine.getActivityControlSurface().attachToActivity(
host.getActivity(),
host.getLifecycle()
);
mSyncer = FlutterBoost.instance().containerManager().generateSyncer(this); mSyncer = FlutterBoost.instance().containerManager().generateSyncer(this);
ensureAlive(); ensureAlive();
...@@ -176,13 +171,19 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -176,13 +171,19 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
Log.v(TAG, "onResume()"); Log.v(TAG, "onResume()");
ensureAlive(); ensureAlive();
flutterEngine.getLifecycleChannel().appIsResumed(); flutterEngine.getLifecycleChannel().appIsResumed();
if(ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE==0||
ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE!=this.host.getActivity().hashCode()){
flutterEngine.getActivityControlSurface().detachFromActivityForConfigChanges();
flutterEngine.getActivityControlSurface().attachToActivity( flutterEngine.getActivityControlSurface().attachToActivity(
host.getActivity(), host.getActivity(),
host.getLifecycle() host.getLifecycle()
); );
ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE=this.host.getActivity().hashCode();
}
if(platformPlugin!=null)
platformPlugin.attachToActivity( host.getActivity());
} }
...@@ -191,7 +192,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -191,7 +192,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
public void onPostResume() { public void onPostResume() {
Log.v(TAG, "onPostResume()"); Log.v(TAG, "onPostResume()");
ensureAlive(); ensureAlive();
// Utils.setStatusBarLightMode(host.getActivity(), true);
} }
...@@ -230,10 +230,15 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -230,10 +230,15 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
// Null out the platformPlugin to avoid a possible retain cycle between the plugin, this Fragment, // Null out the platformPlugin to avoid a possible retain cycle between the plugin, this Fragment,
// and this Fragment's Activity. // and this Fragment's Activity.
if (platformPlugin != null) { if (platformPlugin != null) {
// platformPlugin.destroy(); platformPlugin.detachActivity();
platformPlugin = null; platformPlugin = null;
} }
if(ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE!=0||
ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE==this.host.getActivity().hashCode()){
flutterEngine.getActivityControlSurface().detachFromActivityForConfigChanges();
}
Utils.fixInputMethodManagerLeak(host.getActivity()); Utils.fixInputMethodManagerLeak(host.getActivity());
} }
...@@ -461,7 +466,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -461,7 +466,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
* Flutter experience should control system chrome. * Flutter experience should control system chrome.
*/ */
@Nullable @Nullable
PlatformPlugin providePlatformPlugin(@Nullable Activity activity, @NonNull FlutterEngine flutterEngine); XPlatformPlugin providePlatformPlugin( @NonNull FlutterEngine flutterEngine);
/** /**
* Hook for the host to configure the {@link FlutterEngine} as desired. * Hook for the host to configure the {@link FlutterEngine} as desired.
......
...@@ -16,6 +16,7 @@ import androidx.fragment.app.FragmentActivity; ...@@ -16,6 +16,7 @@ import androidx.fragment.app.FragmentActivity;
import com.idlefish.flutterboost.FlutterBoost; import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.Utils; import com.idlefish.flutterboost.Utils;
import com.idlefish.flutterboost.XFlutterView; import com.idlefish.flutterboost.XFlutterView;
import com.idlefish.flutterboost.XPlatformPlugin;
import io.flutter.embedding.android.*; import io.flutter.embedding.android.*;
import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterShellArgs; import io.flutter.embedding.engine.FlutterShellArgs;
...@@ -467,12 +468,9 @@ public class FlutterFragment extends Fragment implements FlutterActivityAndFragm ...@@ -467,12 +468,9 @@ public class FlutterFragment extends Fragment implements FlutterActivityAndFragm
@Nullable @Nullable
@Override @Override
public PlatformPlugin providePlatformPlugin(@Nullable Activity activity, @NonNull FlutterEngine flutterEngine) { public XPlatformPlugin providePlatformPlugin( @NonNull FlutterEngine flutterEngine) {
if (activity != null) { return new XPlatformPlugin(flutterEngine.getPlatformChannel());
return new PlatformPlugin(getActivity(), flutterEngine.getPlatformChannel());
} else {
return null;
}
} }
/** /**
......
...@@ -16,20 +16,26 @@ class _MyAppState extends State<MyApp> { ...@@ -16,20 +16,26 @@ class _MyAppState extends State<MyApp> {
void initState() { void initState() {
super.initState(); super.initState();
FlutterBoost.singleton.registerPageBuilders({ FlutterBoost.singleton.registerPageBuilders(<String, PageBuilder>{
'embeded': (pageName, params, _)=>EmbededFirstRouteWidget(), 'embeded': (String pageName, Map<String, dynamic> params, String _) =>
'first': (pageName, params, _) => FirstRouteWidget(), EmbeddedFirstRouteWidget(),
'firstFirst': (pageName, params, _) => FirstFirstRouteWidget(), 'first': (String pageName, Map<String, dynamic> params, String _) => FirstRouteWidget(),
'second': (pageName, params, _) => SecondRouteWidget(), 'firstFirst': (String pageName, Map<String, dynamic> params, String _) =>
'secondStateful': (pageName, params, _) => SecondStatefulRouteWidget(), FirstFirstRouteWidget(),
'tab': (pageName, params, _) => TabRouteWidget(), 'second': (String pageName, Map<String, dynamic> params, String _) => SecondRouteWidget(),
'platformView': (pageName, params, _) => PlatformRouteWidget(), 'secondStateful': (String pageName, Map<String, dynamic> params, String _) =>
'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params), 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 来传递参数 ///可以在native层通过 getContainerParams 来传递参数
'flutterPage': (pageName, params, _) { 'flutterPage': (String pageName, Map<String, dynamic> params, String _) {
print("flutterPage params:$params"); print('flutterPage params:$params');
return FlutterRouteWidget(params:params); return FlutterRouteWidget(params: params);
}, },
}); });
FlutterBoost.singleton.addBoostNavigatorObserver(TestBoostNavigatorObserver()); FlutterBoost.singleton.addBoostNavigatorObserver(TestBoostNavigatorObserver());
...@@ -40,31 +46,36 @@ class _MyAppState extends State<MyApp> { ...@@ -40,31 +46,36 @@ class _MyAppState extends State<MyApp> {
return MaterialApp( return MaterialApp(
title: 'Flutter Boost example', title: 'Flutter Boost example',
builder: FlutterBoost.init(postPush: _onRoutePushed), builder: FlutterBoost.init(postPush: _onRoutePushed),
home: Container( home: Container(color: Colors.white));
color:Colors.white
));
} }
void _onRoutePushed( 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) { void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
print("flutterboost#didPop"); print('flutterboost#didPop');
} }
@override
void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) { void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) {
print("flutterboost#didRemove"); print('flutterboost#didRemove');
} }
@override
void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) { void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {
print("flutterboost#didReplace"); print('flutterboost#didReplace');
} }
} }
...@@ -3,7 +3,7 @@ import 'package:flutter/foundation.dart'; ...@@ -3,7 +3,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
typedef void TextViewCreatedCallback(TextViewController controller); typedef TextViewCreatedCallback = void Function(TextViewController controller);
class TextView extends StatefulWidget { class TextView extends StatefulWidget {
const TextView({ const TextView({
...@@ -34,13 +34,13 @@ class _TextViewState extends State<TextView> { ...@@ -34,13 +34,13 @@ class _TextViewState extends State<TextView> {
if (widget.onTextViewCreated == null) { if (widget.onTextViewCreated == null) {
return; return;
} }
widget.onTextViewCreated(new TextViewController._(id)); widget.onTextViewCreated(TextViewController._(id));
} }
} }
class TextViewController { class TextViewController {
TextViewController._(int id) TextViewController._(int id)
: _channel = new MethodChannel('plugins.felix.angelov/textview_$id'); : _channel = MethodChannel('plugins.felix.angelov/textview_$id');
final MethodChannel _channel; final MethodChannel _channel;
......
This diff is collapsed.
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class TestPage extends StatefulWidget { 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; final String title;
...@@ -18,24 +21,16 @@ class _TestPageState extends State<TestPage> { ...@@ -18,24 +21,16 @@ class _TestPageState extends State<TestPage> {
}); });
} }
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: Text(widget.title)),
title: Text(widget.title),
),
body: SafeArea( body: SafeArea(
bottom: false, bottom: false,
child: ListView( child: ListView(
children: <Widget>[ children: <Widget>[
Container( Container(
child: Text( child: const Text(
'You have pushed the button this many times:', 'You have pushed the button this many times:',
), ),
margin: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0),
...@@ -50,10 +45,7 @@ class _TestPageState extends State<TestPage> { ...@@ -50,10 +45,7 @@ class _TestPageState extends State<TestPage> {
alignment: Alignment.center, alignment: Alignment.center,
), ),
Container( Container(
child: TextField( child: const TextField(minLines: 2, maxLines: 10),
minLines: 2,
maxLines: 10,
),
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
), ),
TestTextField(), TestTextField(),
...@@ -98,15 +90,13 @@ class _TestPageState extends State<TestPage> { ...@@ -98,15 +90,13 @@ class _TestPageState extends State<TestPage> {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
), ),
Container( Container(
child: TextField( child: const TextField(minLines: 2, maxLines: 10),
minLines: 2,
maxLines: 10,
),
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
), ),
TestTextField(), TestTextField(),
], ],
)), ),
),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter, onPressed: _incrementCounter,
tooltip: 'Increment', tooltip: 'Increment',
...@@ -123,22 +113,22 @@ class TestTextField extends StatefulWidget { ...@@ -123,22 +113,22 @@ class TestTextField extends StatefulWidget {
class _TestTextFieldState extends State<TestTextField> { class _TestTextFieldState extends State<TestTextField> {
FocusNode _node; FocusNode _node;
PersistentBottomSheetController _controller; PersistentBottomSheetController<dynamic> _controller;
@override @override
void initState() { void initState() {
// TODO: implement initState
super.initState(); super.initState();
_node = FocusNode(); _node = FocusNode();
_node.addListener(() { _node.addListener(() {
if (_node.hasFocus) { if (_node.hasFocus) {
print('showBottomSheet'); print('showBottomSheet');
_controller = Scaffold.of(context) _controller = Scaffold.of(context).showBottomSheet<dynamic>(
.showBottomSheet<dynamic>((BuildContext ctx) => Container( (BuildContext ctx) => Container(
width: double.infinity, width: double.infinity,
height: 36.0, height: 36.0,
color: Colors.deepPurple, color: Colors.deepPurple,
)); ),
);
} else { } else {
if (_controller != null) { if (_controller != null) {
//Navigator.of(context).pop(); //Navigator.of(context).pop();
......
...@@ -6,13 +6,12 @@ ...@@ -6,13 +6,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_boost_example/main.dart';
import '../lib/main.dart';
void main() { void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async { testWidgets('Verify Platform version', (WidgetTester tester) async {
// Build our app and trigger a frame. // Build our app and trigger a frame.
await tester.pumpWidget(new MyApp()); await tester.pumpWidget(MyApp());
// Verify that platform version is retrieved. // Verify that platform version is retrieved.
expect( expect(
......
...@@ -16,17 +16,22 @@ class _MyAppState extends State<MyApp> { ...@@ -16,17 +16,22 @@ class _MyAppState extends State<MyApp> {
void initState() { void initState() {
super.initState(); super.initState();
FlutterBoost.singleton.registerPageBuilders({ FlutterBoost.singleton.registerPageBuilders(<String, PageBuilder>{
'first': (pageName, params, _) => FirstRouteWidget(), 'first': (String pageName, Map<String, dynamic> params, String _) =>
'second': (pageName, params, _) => SecondRouteWidget(), FirstRouteWidget(),
'tab': (pageName, params, _) => TabRouteWidget(), 'second': (String pageName, Map<String, dynamic> params, String _) =>
'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params), SecondRouteWidget(),
'tab': (String pageName, Map<String, dynamic> params, String _) =>
TabRouteWidget(),
'flutterFragment':
(String pageName, Map<String, dynamic> params, String _) =>
FragmentRouteWidget(params),
///可以在native层通过 getContainerParams 来传递参数 ///可以在native层通过 getContainerParams 来传递参数
'flutterPage': (pageName, params, _) { 'flutterPage': (String pageName, Map<String, dynamic> params, String _) {
print("flutterPage params:$params"); print('flutterPage params:$params');
return FlutterRouteWidget(); return const FlutterRouteWidget();
}, },
}); });
} }
...@@ -36,10 +41,15 @@ class _MyAppState extends State<MyApp> { ...@@ -36,10 +41,15 @@ class _MyAppState extends State<MyApp> {
return MaterialApp( return MaterialApp(
title: 'Flutter Boost example', title: 'Flutter Boost example',
builder: FlutterBoost.init(postPush: _onRoutePushed), builder: FlutterBoost.init(postPush: _onRoutePushed),
home: Container()); home: Container(),
);
} }
void _onRoutePushed( void _onRoutePushed(
String pageName, String uniqueId, Map params, Route route, Future _) { String pageName,
} String uniqueId,
Map<String, dynamic> params,
Route<dynamic> route,
Future<dynamic> _,
) {}
} }
...@@ -6,15 +6,18 @@ class FirstRouteWidget extends StatelessWidget { ...@@ -6,15 +6,18 @@ class FirstRouteWidget extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('First Route'), title: const Text('First Route'),
), ),
body: Center( body: Center(
child: RaisedButton( child: RaisedButton(
child: Text('Open second route'), child: const Text('Open second route'),
onPressed: () { onPressed: () {
print("open second page!"); print('open second page!');
FlutterBoost.singleton.open("second").then((Map value) { FlutterBoost.singleton
print("call me when page is finished. did recieve second route result $value"); .open('second')
.then((Map<String, dynamic> value) {
print(
'call me when page is finished. did recieve second route result $value');
}); });
}, },
), ),
...@@ -28,19 +31,21 @@ class SecondRouteWidget extends StatelessWidget { ...@@ -28,19 +31,21 @@ class SecondRouteWidget extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text("Second Route"), title: const Text('Second Route'),
), ),
body: Center( body: Center(
child: RaisedButton( child: RaisedButton(
onPressed: () { onPressed: () {
// Navigate back to first route when tapped. // Navigate back to first route when tapped.
BoostContainerSettings settings = final BoostContainerSettings settings =
BoostContainer.of(context).settings; BoostContainer.of(context).settings;
FlutterBoost.singleton.close(settings.uniqueId, FlutterBoost.singleton.close(
result: <dynamic,dynamic>{"result": "data from second"}); 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 { ...@@ -51,15 +56,13 @@ class TabRouteWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('Tab Route')),
title: Text("Tab Route"),
),
body: Center( body: Center(
child: RaisedButton( child: RaisedButton(
onPressed: () { 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 { ...@@ -67,15 +70,15 @@ class TabRouteWidget extends StatelessWidget {
} }
class FlutterRouteWidget extends StatelessWidget { class FlutterRouteWidget extends StatelessWidget {
final String message; const FlutterRouteWidget({this.message});
FlutterRouteWidget({this.message}); final String message;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('flutter_boost_example'), title: const Text('flutter_boost_example'),
), ),
body: Column( body: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
...@@ -83,7 +86,7 @@ class FlutterRouteWidget extends StatelessWidget { ...@@ -83,7 +86,7 @@ class FlutterRouteWidget extends StatelessWidget {
Container( Container(
margin: const EdgeInsets.only(top: 80.0), margin: const EdgeInsets.only(top: 80.0),
child: Text( child: Text(
message ?? "This is a flutter activity", message ?? 'This is a flutter activity',
style: TextStyle(fontSize: 28.0, color: Colors.blue), style: TextStyle(fontSize: 28.0, color: Colors.blue),
), ),
alignment: AlignmentDirectional.center, alignment: AlignmentDirectional.center,
...@@ -101,10 +104,12 @@ class FlutterRouteWidget extends StatelessWidget { ...@@ -101,10 +104,12 @@ class FlutterRouteWidget extends StatelessWidget {
///后面的参数会在native的IPlatform.startActivity方法回调中拼接到url的query部分。 ///后面的参数会在native的IPlatform.startActivity方法回调中拼接到url的query部分。
///例如:sample://nativePage?aaa=bbb ///例如:sample://nativePage?aaa=bbb
onTap: () => onTap: () => FlutterBoost.singleton.open(
FlutterBoost.singleton.open("sample://nativePage", urlParams: <dynamic,dynamic>{ 'sample://nativePage',
"query": {"aaa": "bbb"} urlParams: <String, dynamic>{
}), 'query': <String, dynamic>{'aaa': 'bbb'}
},
),
), ),
InkWell( InkWell(
child: Container( child: Container(
...@@ -118,10 +123,12 @@ class FlutterRouteWidget extends StatelessWidget { ...@@ -118,10 +123,12 @@ class FlutterRouteWidget extends StatelessWidget {
///后面的参数会在native的IPlatform.startActivity方法回调中拼接到url的query部分。 ///后面的参数会在native的IPlatform.startActivity方法回调中拼接到url的query部分。
///例如:sample://nativePage?aaa=bbb ///例如:sample://nativePage?aaa=bbb
onTap: () => onTap: () => FlutterBoost.singleton.open(
FlutterBoost.singleton.open("sample://flutterPage", urlParams: <dynamic,dynamic>{ 'sample://flutterPage',
"query": {"aaa": "bbb"} urlParams: <String, dynamic>{
}), 'query': <String, dynamic>{'aaa': 'bbb'},
},
),
), ),
InkWell( InkWell(
child: Container( child: Container(
...@@ -131,10 +138,13 @@ class FlutterRouteWidget extends StatelessWidget { ...@@ -131,10 +138,13 @@ class FlutterRouteWidget extends StatelessWidget {
child: Text( child: Text(
'push flutter widget', 'push flutter widget',
style: TextStyle(fontSize: 22.0, color: Colors.black), style: TextStyle(fontSize: 22.0, color: Colors.black),
)), ),
),
onTap: () { onTap: () {
Navigator.push<dynamic>( Navigator.push<dynamic>(
context, MaterialPageRoute<dynamic>(builder: (_) => PushWidget())); context,
MaterialPageRoute<dynamic>(builder: (_) => PushWidget()),
);
}, },
), ),
InkWell( InkWell(
...@@ -145,9 +155,10 @@ class FlutterRouteWidget extends StatelessWidget { ...@@ -145,9 +155,10 @@ class FlutterRouteWidget extends StatelessWidget {
child: Text( child: Text(
'open flutter fragment page', 'open flutter fragment page',
style: TextStyle(fontSize: 22.0, color: Colors.black), style: TextStyle(fontSize: 22.0, color: Colors.black),
)), ),
),
onTap: () => onTap: () =>
FlutterBoost.singleton.open("sample://flutterFragmentPage"), FlutterBoost.singleton.open('sample://flutterFragmentPage'),
), ),
], ],
), ),
...@@ -156,15 +167,15 @@ class FlutterRouteWidget extends StatelessWidget { ...@@ -156,15 +167,15 @@ class FlutterRouteWidget extends StatelessWidget {
} }
class FragmentRouteWidget extends StatelessWidget { class FragmentRouteWidget extends StatelessWidget {
final Map params; const FragmentRouteWidget(this.params);
FragmentRouteWidget(this.params); final Map<String, dynamic> params;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('flutter_boost_example'), title: const Text('flutter_boost_example'),
), ),
body: Column( body: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
...@@ -172,7 +183,7 @@ class FragmentRouteWidget extends StatelessWidget { ...@@ -172,7 +183,7 @@ class FragmentRouteWidget extends StatelessWidget {
Container( Container(
margin: const EdgeInsets.only(top: 80.0), margin: const EdgeInsets.only(top: 80.0),
child: Text( child: Text(
"This is a flutter fragment", 'This is a flutter fragment',
style: TextStyle(fontSize: 28.0, color: Colors.blue), style: TextStyle(fontSize: 28.0, color: Colors.blue),
), ),
alignment: AlignmentDirectional.center, alignment: AlignmentDirectional.center,
...@@ -180,7 +191,7 @@ class FragmentRouteWidget extends StatelessWidget { ...@@ -180,7 +191,7 @@ class FragmentRouteWidget extends StatelessWidget {
Container( Container(
margin: const EdgeInsets.only(top: 32.0), margin: const EdgeInsets.only(top: 32.0),
child: Text( child: Text(
params['tag'] ?? '', '${params['tag']}' ?? '',
style: TextStyle(fontSize: 28.0, color: Colors.red), style: TextStyle(fontSize: 28.0, color: Colors.red),
), ),
alignment: AlignmentDirectional.center, alignment: AlignmentDirectional.center,
...@@ -194,8 +205,9 @@ class FragmentRouteWidget extends StatelessWidget { ...@@ -194,8 +205,9 @@ class FragmentRouteWidget extends StatelessWidget {
child: Text( child: Text(
'open native page', 'open native page',
style: TextStyle(fontSize: 22.0, color: Colors.black), style: TextStyle(fontSize: 22.0, color: Colors.black),
)), ),
onTap: () => FlutterBoost.singleton.open("sample://nativePage"), ),
onTap: () => FlutterBoost.singleton.open('sample://nativePage'),
), ),
InkWell( InkWell(
child: Container( child: Container(
...@@ -205,8 +217,9 @@ class FragmentRouteWidget extends StatelessWidget { ...@@ -205,8 +217,9 @@ class FragmentRouteWidget extends StatelessWidget {
child: Text( child: Text(
'open flutter page', 'open flutter page',
style: TextStyle(fontSize: 22.0, color: Colors.black), style: TextStyle(fontSize: 22.0, color: Colors.black),
)), ),
onTap: () => FlutterBoost.singleton.open("sample://flutterPage"), ),
onTap: () => FlutterBoost.singleton.open('sample://flutterPage'),
), ),
InkWell( InkWell(
child: Container( child: Container(
...@@ -216,9 +229,10 @@ class FragmentRouteWidget extends StatelessWidget { ...@@ -216,9 +229,10 @@ class FragmentRouteWidget extends StatelessWidget {
child: Text( child: Text(
'open flutter fragment page', 'open flutter fragment page',
style: TextStyle(fontSize: 22.0, color: Colors.black), style: TextStyle(fontSize: 22.0, color: Colors.black),
)), ),
),
onTap: () => onTap: () =>
FlutterBoost.singleton.open("sample://flutterFragmentPage"), FlutterBoost.singleton.open('sample://flutterFragmentPage'),
) )
], ],
), ),
...@@ -234,15 +248,8 @@ class PushWidget extends StatefulWidget { ...@@ -234,15 +248,8 @@ class PushWidget extends StatefulWidget {
class _PushWidgetState extends State<PushWidget> { class _PushWidgetState extends State<PushWidget> {
VoidCallback _backPressedListenerUnsub; VoidCallback _backPressedListenerUnsub;
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override @override
void didChangeDependencies() { void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies(); super.didChangeDependencies();
// if (_backPressedListenerUnsub == null) { // if (_backPressedListenerUnsub == null) {
...@@ -258,13 +265,12 @@ class _PushWidgetState extends State<PushWidget> { ...@@ -258,13 +265,12 @@ class _PushWidgetState extends State<PushWidget> {
@override @override
void dispose() { void dispose() {
// TODO: implement dispose
super.dispose(); super.dispose();
_backPressedListenerUnsub?.call(); _backPressedListenerUnsub?.call();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FlutterRouteWidget(message: "Pushed Widget"); return const FlutterRouteWidget(message: 'Pushed Widget');
} }
} }
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class TestPage extends StatefulWidget { 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; final String title;
...@@ -18,24 +21,16 @@ class _TestPageState extends State<TestPage> { ...@@ -18,24 +21,16 @@ class _TestPageState extends State<TestPage> {
}); });
} }
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: Text(widget.title)),
title: Text(widget.title),
),
body: SafeArea( body: SafeArea(
bottom: false, bottom: false,
child: ListView( child: ListView(
children: <Widget>[ children: <Widget>[
Container( Container(
child: Text( child: const Text(
'You have pushed the button this many times:', 'You have pushed the button this many times:',
), ),
margin: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0),
...@@ -50,10 +45,7 @@ class _TestPageState extends State<TestPage> { ...@@ -50,10 +45,7 @@ class _TestPageState extends State<TestPage> {
alignment: Alignment.center, alignment: Alignment.center,
), ),
Container( Container(
child: TextField( child: const TextField(minLines: 2, maxLines: 10),
minLines: 2,
maxLines: 10,
),
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
), ),
TestTextField(), TestTextField(),
...@@ -98,20 +90,18 @@ class _TestPageState extends State<TestPage> { ...@@ -98,20 +90,18 @@ class _TestPageState extends State<TestPage> {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
), ),
Container( Container(
child: TextField( child: const TextField(minLines: 2, maxLines: 10),
minLines: 2,
maxLines: 10,
),
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
), ),
TestTextField(), TestTextField(),
], ],
)), ),
),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter, onPressed: _incrementCounter,
tooltip: 'Increment', tooltip: 'Increment',
child: Icon(Icons.add), child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods. ),
); );
} }
} }
...@@ -123,25 +113,24 @@ class TestTextField extends StatefulWidget { ...@@ -123,25 +113,24 @@ class TestTextField extends StatefulWidget {
class _TestTextFieldState extends State<TestTextField> { class _TestTextFieldState extends State<TestTextField> {
FocusNode _node; FocusNode _node;
PersistentBottomSheetController _controller; PersistentBottomSheetController<dynamic> _controller;
@override @override
void initState() { void initState() {
// TODO: implement initState
super.initState(); super.initState();
_node = FocusNode(); _node = FocusNode();
_node.addListener(() { _node.addListener(() {
if (_node.hasFocus) { if (_node.hasFocus) {
print('showBottomSheet'); print('showBottomSheet');
_controller = Scaffold.of(context) _controller = Scaffold.of(context).showBottomSheet<dynamic>(
.showBottomSheet<dynamic>((BuildContext ctx) => Container( (BuildContext ctx) => Container(
width: double.infinity, width: double.infinity,
height: 36.0, height: 36.0,
color: Colors.deepPurple, color: Colors.deepPurple,
)); ),
);
} else { } else {
if (_controller != null) { if (_controller != null) {
//Navigator.of(context).pop();
print('closeBottomSheet'); print('closeBottomSheet');
_controller.close(); _controller.close();
} }
......
...@@ -24,30 +24,30 @@ ...@@ -24,30 +24,30 @@
import 'dart:async'; import 'dart:async';
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/services.dart';
typedef Future<dynamic> EventListener(String name, Map arguments); import 'package:flutter/services.dart';
typedef Future<dynamic> MethodHandler(MethodCall call);
class BoostChannel { typedef EventListener = Future<dynamic> Function(
final MethodChannel _methodChannel = MethodChannel("flutter_boost"); String name, Map<String, dynamic> arguments);
final Map<String, List<EventListener>> _eventListeners = Map(); typedef MethodHandler = Future<dynamic> Function(MethodCall call);
final Set<MethodHandler> _methodHandlers = Set();
class BoostChannel {
BoostChannel() { BoostChannel() {
_methodChannel.setMethodCallHandler((MethodCall call) { _methodChannel.setMethodCallHandler((MethodCall call) {
if (call.method == "__event__") { if (call.method == '__event__') {
String name = call.arguments["name"]; final String name = call.arguments['name'] as String;
Map arg = call.arguments["arguments"]; final Map<String, dynamic> arg =
List<EventListener> list = _eventListeners[name]; (call.arguments['arguments'] as Map<dynamic, dynamic>)
?.cast<String, dynamic>();
final List<EventListener> list = _eventListeners[name];
if (list != null) { if (list != null) {
for (EventListener l in list) { for (final EventListener l in list) {
l(name, arg); l(name, arg);
} }
} }
} else { } else {
for (MethodHandler handler in _methodHandlers) { for (final MethodHandler handler in _methodHandlers) {
handler(call); handler(call);
} }
} }
...@@ -56,37 +56,41 @@ class BoostChannel { ...@@ -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) { if (name == null) {
return; return;
} }
if (arguments == null) { arguments ??= <String, dynamic>{};
arguments = Map<dynamic, dynamic>();
}
Map msg = Map<dynamic, dynamic>(); final Map<String, dynamic> msg = <String, dynamic>{};
msg["name"] = name; msg['name'] = name;
msg["arguments"] = arguments; msg['arguments'] = arguments;
_methodChannel.invokeMethod<dynamic>("__event__", msg); _methodChannel.invokeMethod<dynamic>('__event__', msg);
} }
Future<T> invokeMethod<T>(String method, [dynamic arguments]) async { Future<T> invokeMethod<T>(String method, [dynamic arguments]) async {
assert(method != "__event__"); assert(method != '__event__');
return _methodChannel.invokeMethod<T>(method, arguments); return _methodChannel.invokeMethod<T>(method, arguments);
} }
Future<List<T>> invokeListMethod<T>(String method, Future<List<T>> invokeListMethod<T>(String method,
[dynamic arguments]) async { [dynamic arguments]) async {
assert(method != "__event__"); assert(method != '__event__');
return _methodChannel.invokeListMethod<T>(method, arguments); return _methodChannel.invokeListMethod<T>(method, arguments);
} }
Future<Map<K, V>> invokeMapMethod<K, V>(String method, Future<Map<K, V>> invokeMapMethod<K, V>(String method,
[dynamic arguments]) async { [dynamic arguments]) async {
assert(method != "__event__"); assert(method != '__event__');
return _methodChannel.invokeMapMethod<K, V>(method, arguments); return _methodChannel.invokeMapMethod<K, V>(method, arguments);
} }
...@@ -94,9 +98,11 @@ class BoostChannel { ...@@ -94,9 +98,11 @@ class BoostChannel {
VoidCallback addEventListener(String name, EventListener listener) { VoidCallback addEventListener(String name, EventListener listener) {
assert(name != null && listener != null); assert(name != null && listener != null);
List<EventListener> list = _eventListeners[name]; List<EventListener> list;
list = _eventListeners[name];
if (list == null) { if (list == null) {
list = List(); list = <EventListener>[];
_eventListeners[name] = list; _eventListeners[name] = list;
} }
......
...@@ -22,10 +22,11 @@ ...@@ -22,10 +22,11 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'container_manager.dart';
import '../flutter_boost.dart'; import '../flutter_boost.dart';
import 'boost_page_route.dart';
import '../support/logger.dart'; import '../support/logger.dart';
import 'boost_page_route.dart';
import 'container_manager.dart';
enum ContainerLifeCycle { enum ContainerLifeCycle {
Init, Init,
...@@ -37,28 +38,31 @@ enum ContainerLifeCycle { ...@@ -37,28 +38,31 @@ enum ContainerLifeCycle {
Foreground Foreground
} }
typedef void BoostContainerLifeCycleObserver( typedef BoostContainerLifeCycleObserver = void Function(
ContainerLifeCycle state, BoostContainerSettings settings); ContainerLifeCycle state,
BoostContainerSettings settings,
);
class BoostContainer extends Navigator { class BoostContainer extends Navigator {
final BoostContainerSettings settings; const BoostContainer({
GlobalKey<BoostContainerState> key,
const BoostContainer(
{GlobalKey<BoostContainerState> key,
this.settings = const BoostContainerSettings(), this.settings = const BoostContainerSettings(),
String initialRoute, String initialRoute,
RouteFactory onGenerateRoute, RouteFactory onGenerateRoute,
RouteFactory onUnknownRoute, RouteFactory onUnknownRoute,
List<NavigatorObserver> observers}) List<NavigatorObserver> observers,
: super( }) : super(
key: key, key: key,
initialRoute: initialRoute, initialRoute: initialRoute,
onGenerateRoute: onGenerateRoute, onGenerateRoute: onGenerateRoute,
onUnknownRoute: onUnknownRoute, onUnknownRoute: onUnknownRoute,
observers: observers); observers: observers,
);
factory BoostContainer.copy(Navigator navigator, factory BoostContainer.copy(
[BoostContainerSettings settings = const BoostContainerSettings()]) => Navigator navigator, [
BoostContainerSettings settings = const BoostContainerSettings(),
]) =>
BoostContainer( BoostContainer(
key: GlobalKey<BoostContainerState>(), key: GlobalKey<BoostContainerState>(),
settings: settings, settings: settings,
...@@ -69,7 +73,9 @@ class BoostContainer extends Navigator { ...@@ -69,7 +73,9 @@ class BoostContainer extends Navigator {
); );
factory BoostContainer.obtain( factory BoostContainer.obtain(
Navigator navigator, BoostContainerSettings settings) => Navigator navigator,
BoostContainerSettings settings,
) =>
BoostContainer( BoostContainer(
key: GlobalKey<BoostContainerState>(), key: GlobalKey<BoostContainerState>(),
settings: settings, settings: settings,
...@@ -81,7 +87,8 @@ class BoostContainer extends Navigator { ...@@ -81,7 +87,8 @@ class BoostContainer extends Navigator {
uniqueId: settings.uniqueId, uniqueId: settings.uniqueId,
animated: false, animated: false,
settings: routeSettings, settings: routeSettings,
builder: settings.builder); builder: settings.builder,
);
} else { } else {
return navigator.onGenerateRoute(routeSettings); return navigator.onGenerateRoute(routeSettings);
} }
...@@ -90,7 +97,10 @@ class BoostContainer extends Navigator { ...@@ -90,7 +97,10 @@ class BoostContainer extends Navigator {
ContainerNavigatorObserver.bindContainerManager(), ContainerNavigatorObserver.bindContainerManager(),
HeroController(), HeroController(),
], ],
onUnknownRoute: navigator.onUnknownRoute); onUnknownRoute: navigator.onUnknownRoute,
);
final BoostContainerSettings settings;
@override @override
BoostContainerState createState() => BoostContainerState(); BoostContainerState createState() => BoostContainerState();
...@@ -121,7 +131,7 @@ class BoostContainerState extends NavigatorState { ...@@ -121,7 +131,7 @@ class BoostContainerState extends NavigatorState {
String get name => widget.settings.name; 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; BoostContainerSettings get settings => widget.settings;
...@@ -138,7 +148,7 @@ class BoostContainerState extends NavigatorState { ...@@ -138,7 +148,7 @@ class BoostContainerState extends NavigatorState {
ContainerNavigatorObserver findContainerNavigatorObserver( ContainerNavigatorObserver findContainerNavigatorObserver(
Navigator navigator) { Navigator navigator) {
for (NavigatorObserver observer in navigator.observers) { for (final NavigatorObserver observer in navigator.observers) {
if (observer is ContainerNavigatorObserver) { if (observer is ContainerNavigatorObserver) {
return observer; return observer;
} }
...@@ -153,11 +163,6 @@ class BoostContainerState extends NavigatorState { ...@@ -153,11 +163,6 @@ class BoostContainerState extends NavigatorState {
backPressedHandler = () => maybePop(); backPressedHandler = () => maybePop();
} }
@override
void didUpdateWidget(Navigator oldWidget) {
super.didUpdateWidget(oldWidget);
}
@override @override
void dispose() { void dispose() {
routerHistory.clear(); routerHistory.clear();
...@@ -172,7 +177,7 @@ class BoostContainerState extends NavigatorState { ...@@ -172,7 +177,7 @@ class BoostContainerState extends NavigatorState {
@override @override
Future<bool> maybePop<T extends Object>([T result]) async { 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(); final RoutePopDisposition disposition = await route.willPop();
if (mounted) { if (mounted) {
switch (disposition) { switch (disposition) {
...@@ -216,10 +221,10 @@ class BoostContainerState extends NavigatorState { ...@@ -216,10 +221,10 @@ class BoostContainerState extends NavigatorState {
Route<T> newRoute; Route<T> newRoute;
if (FlutterBoost.containerManager.prePushRoute != null) { if (FlutterBoost.containerManager.prePushRoute != null) {
newRoute = FlutterBoost.containerManager 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); routerHistory.add(route);
...@@ -233,25 +238,30 @@ class BoostContainerState extends NavigatorState { ...@@ -233,25 +238,30 @@ class BoostContainerState extends NavigatorState {
VoidCallback addLifeCycleObserver(BoostContainerLifeCycleObserver observer) { VoidCallback addLifeCycleObserver(BoostContainerLifeCycleObserver observer) {
return FlutterBoost.singleton.addBoostContainerLifeCycleObserver( return FlutterBoost.singleton.addBoostContainerLifeCycleObserver(
(ContainerLifeCycle state, BoostContainerSettings settings) { (
ContainerLifeCycle state,
BoostContainerSettings settings,
) {
if (settings.uniqueId == uniqueId) { if (settings.uniqueId == uniqueId) {
observer(state, settings); observer(state, settings);
} }
}); },
);
} }
} }
class BoostContainerSettings { class BoostContainerSettings {
const BoostContainerSettings({
this.uniqueId = 'default',
this.name = 'default',
this.params,
this.builder,
});
final String uniqueId; final String uniqueId;
final String name; final String name;
final Map params; final Map<String, dynamic> params;
final WidgetBuilder builder; final WidgetBuilder builder;
const BoostContainerSettings(
{this.uniqueId = 'default',
this.name = 'default',
this.params,
this.builder});
} }
class ContainerElement extends StatefulElement { class ContainerElement extends StatefulElement {
...@@ -259,13 +269,13 @@ class ContainerElement extends StatefulElement { ...@@ -259,13 +269,13 @@ class ContainerElement extends StatefulElement {
} }
class ContainerNavigatorObserver extends NavigatorObserver { class ContainerNavigatorObserver extends NavigatorObserver {
static final Set<NavigatorObserver> boostObservers = Set<NavigatorObserver>();
ContainerNavigatorObserver(); ContainerNavigatorObserver();
factory ContainerNavigatorObserver.bindContainerManager() => factory ContainerNavigatorObserver.bindContainerManager() =>
ContainerNavigatorObserver(); ContainerNavigatorObserver();
static final Set<NavigatorObserver> boostObservers = <NavigatorObserver>{};
VoidCallback addBoostNavigatorObserver(NavigatorObserver observer) { VoidCallback addBoostNavigatorObserver(NavigatorObserver observer) {
boostObservers.add(observer); boostObservers.add(observer);
...@@ -278,28 +288,28 @@ class ContainerNavigatorObserver extends NavigatorObserver { ...@@ -278,28 +288,28 @@ class ContainerNavigatorObserver extends NavigatorObserver {
@override @override
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) { void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
for (NavigatorObserver observer in boostObservers) { for (final NavigatorObserver observer in boostObservers) {
observer.didPush(route, previousRoute); observer.didPush(route, previousRoute);
} }
} }
@override @override
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) { void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
for (NavigatorObserver observer in boostObservers) { for (final NavigatorObserver observer in boostObservers) {
observer.didPop(route, previousRoute); observer.didPop(route, previousRoute);
} }
} }
@override @override
void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) { void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) {
for (NavigatorObserver observer in boostObservers) { for (final NavigatorObserver observer in boostObservers) {
observer.didRemove(route, previousRoute); observer.didRemove(route, previousRoute);
} }
} }
@override @override
void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) { 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); observer.didReplace(newRoute: newRoute, oldRoute: oldRoute);
} }
} }
......
...@@ -25,26 +25,25 @@ ...@@ -25,26 +25,25 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter/material.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> { 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 pageName;
final String uniqueId; final String uniqueId;
final Map params; final Map<String, dynamic> params;
final bool animated; final bool animated;
final WidgetBuilder builder;
final RouteSettings settings;
final Set<VoidCallback> backPressedListeners = Set<VoidCallback>(); final Set<VoidCallback> backPressedListeners = <VoidCallback>{};
BoostPageRoute(
{this.pageName,
this.params,
this.uniqueId,
this.animated,
this.builder,
this.settings})
: super(builder: builder, settings: settings);
static BoostPageRoute<T> of<T>(BuildContext context) { static BoostPageRoute<T> of<T>(BuildContext context) {
final Route<T> route = ModalRoute.of(context); final Route<T> route = ModalRoute.of(context);
......
This diff is collapsed.
...@@ -23,10 +23,11 @@ ...@@ -23,10 +23,11 @@
*/ */
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'boost_container.dart';
import 'container_coordinator.dart';
import '../flutter_boost.dart'; import '../flutter_boost.dart';
import '../support/logger.dart'; import '../support/logger.dart';
import 'boost_container.dart';
import 'container_coordinator.dart';
enum ContainerOperation { Push, Onstage, Pop, Remove } enum ContainerOperation { Push, Onstage, Pop, Remove }
...@@ -35,12 +36,16 @@ typedef BoostContainerObserver = void Function( ...@@ -35,12 +36,16 @@ typedef BoostContainerObserver = void Function(
@immutable @immutable
class BoostContainerManager extends StatefulWidget { class BoostContainerManager extends StatefulWidget {
const BoostContainerManager({
Key key,
this.initNavigator,
this.prePushRoute,
this.postPushRoute,
}) : super(key: key);
final Navigator initNavigator; final Navigator initNavigator;
final PrePushRoute prePushRoute; final PrePushRoute prePushRoute;
final PostPushRoute postPushRoute; final PostPushRoute postPushRoute;
const BoostContainerManager(
{Key key, this.initNavigator, this.prePushRoute, this.postPushRoute})
: super(key: key);
@override @override
ContainerManagerState createState() => ContainerManagerState(); ContainerManagerState createState() => ContainerManagerState();
...@@ -76,15 +81,15 @@ class ContainerManagerState extends State<BoostContainerManager> { ...@@ -76,15 +81,15 @@ class ContainerManagerState extends State<BoostContainerManager> {
bool get foreground => _foreground; bool get foreground => _foreground;
//Number of containers. // Number of containers.
int get containerCounts => _offstage.length; int get containerCounts => _offstage.length;
List<BoostContainer> get offstage => _offstage; List<BoostContainer> get offstage => _offstage;
//Setting for current visible container. // Setting for current visible container.
BoostContainerSettings get onstageSettings => _onstage.settings; BoostContainerSettings get onstageSettings => _onstage.settings;
//Current visible container. // Current visible container.
BoostContainerState get onstageContainer => _stateOf(_onstage); BoostContainerState get onstageContainer => _stateOf(_onstage);
BoostContainerState get subContainer => BoostContainerState get subContainer =>
...@@ -118,8 +123,7 @@ class ContainerManagerState extends State<BoostContainerManager> { ...@@ -118,8 +123,7 @@ class ContainerManagerState extends State<BoostContainerManager> {
} }
BoostContainerState _stateOf(BoostContainer container) { BoostContainerState _stateOf(BoostContainer container) {
if (container.key != null && if (container.key is GlobalKey<BoostContainerState>) {
container.key is GlobalKey<BoostContainerState>) {
final GlobalKey<BoostContainerState> globalKey = final GlobalKey<BoostContainerState> globalKey =
container.key as GlobalKey<BoostContainerState>; container.key as GlobalKey<BoostContainerState>;
return globalKey.currentState; return globalKey.currentState;
...@@ -133,7 +137,7 @@ class ContainerManagerState extends State<BoostContainerManager> { ...@@ -133,7 +137,7 @@ class ContainerManagerState extends State<BoostContainerManager> {
void _onShownContainerChanged(String old, String now) { void _onShownContainerChanged(String old, String now) {
Logger.log('onShownContainerChanged old:$old now:$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['newName'] = now;
properties['oldName'] = old; properties['oldName'] = old;
...@@ -149,7 +153,7 @@ class ContainerManagerState extends State<BoostContainerManager> { ...@@ -149,7 +153,7 @@ class ContainerManagerState extends State<BoostContainerManager> {
} }
if (_leastEntries != null && _leastEntries.isNotEmpty) { if (_leastEntries != null && _leastEntries.isNotEmpty) {
for (_ContainerOverlayEntry entry in _leastEntries) { for (final _ContainerOverlayEntry entry in _leastEntries) {
entry.remove(); entry.remove();
} }
} }
...@@ -223,7 +227,7 @@ class ContainerManagerState extends State<BoostContainerManager> { ...@@ -223,7 +227,7 @@ class ContainerManagerState extends State<BoostContainerManager> {
setState(() {}); setState(() {});
for (BoostContainerObserver observer in FlutterBoost for (final BoostContainerObserver observer in FlutterBoost
.singleton.observersHolder .singleton.observersHolder
.observersOf<BoostContainerObserver>()) { .observersOf<BoostContainerObserver>()) {
observer(ContainerOperation.Onstage, _onstage.settings); observer(ContainerOperation.Onstage, _onstage.settings);
...@@ -265,7 +269,7 @@ class ContainerManagerState extends State<BoostContainerManager> { ...@@ -265,7 +269,7 @@ class ContainerManagerState extends State<BoostContainerManager> {
setState(() {}); setState(() {});
for (BoostContainerObserver observer in FlutterBoost for (final BoostContainerObserver observer in FlutterBoost
.singleton.observersHolder .singleton.observersHolder
.observersOf<BoostContainerObserver>()) { .observersOf<BoostContainerObserver>()) {
observer(ContainerOperation.Push, _onstage.settings); observer(ContainerOperation.Push, _onstage.settings);
...@@ -280,9 +284,11 @@ class ContainerManagerState extends State<BoostContainerManager> { ...@@ -280,9 +284,11 @@ class ContainerManagerState extends State<BoostContainerManager> {
_onstage = _offstage.removeLast(); _onstage = _offstage.removeLast();
setState(() {}); setState(() {});
for (BoostContainerObserver observer in FlutterBoost final Set<BoostContainerObserver> observers = FlutterBoost
.singleton.observersHolder .singleton.observersHolder
.observersOf<BoostContainerObserver>()) { .observersOf<BoostContainerObserver>();
for (final BoostContainerObserver observer in observers) {
observer(ContainerOperation.Pop, old.settings); observer(ContainerOperation.Pop, old.settings);
} }
...@@ -295,31 +301,33 @@ class ContainerManagerState extends State<BoostContainerManager> { ...@@ -295,31 +301,33 @@ class ContainerManagerState extends State<BoostContainerManager> {
} else { } else {
final BoostContainer container = _offstage.firstWhere( final BoostContainer container = _offstage.firstWhere(
(BoostContainer container) => container.settings.uniqueId == uniqueId, (BoostContainer container) => container.settings.uniqueId == uniqueId,
orElse: () => null); orElse: () => null,
);
if (container != null) { if (container != null) {
_offstage.remove(container); _offstage.remove(container);
setState(() {}); setState(() {});
for (BoostContainerObserver observer in FlutterBoost final Set<BoostContainerObserver> observers = FlutterBoost
.singleton.observersHolder .singleton.observersHolder
.observersOf<BoostContainerObserver>()) { .observersOf<BoostContainerObserver>();
for (final BoostContainerObserver observer in observers) {
observer(ContainerOperation.Remove, container.settings); observer(ContainerOperation.Remove, container.settings);
} }
Logger.log('ContainerObserver#2 didRemove'); Logger.log('ContainerObserver#2 didRemove');
} }
} }
return null;
} }
bool canPop() => _offstage.isNotEmpty; bool canPop() => _offstage.isNotEmpty;
String dump() { 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()}'; info = '$info\n ${container?.desc()}';
} }
...@@ -328,21 +336,21 @@ class ContainerManagerState extends State<BoostContainerManager> { ...@@ -328,21 +336,21 @@ class ContainerManagerState extends State<BoostContainerManager> {
} }
class _ContainerOverlayEntry extends OverlayEntry { class _ContainerOverlayEntry extends OverlayEntry {
bool _removed = false;
_ContainerOverlayEntry(BoostContainer container) _ContainerOverlayEntry(BoostContainer container)
: super( : super(
builder: (BuildContext ctx) => container, builder: (BuildContext ctx) => container,
opaque: true, opaque: true,
maintainState: true); maintainState: true,
);
bool _removed = false;
@override @override
void remove() { void remove() {
assert(!_removed); assert(!_removed);
if (_removed) { if (_removed) {
return; return;
} }
_removed = true; _removed = true;
super.remove(); super.remove();
} }
......
...@@ -25,58 +25,78 @@ import 'dart:async'; ...@@ -25,58 +25,78 @@ import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'container/boost_container.dart';
import 'container/container_manager.dart';
import 'channel/boost_channel.dart'; import 'channel/boost_channel.dart';
import 'container/boost_container.dart';
import 'container/container_coordinator.dart'; import 'container/container_coordinator.dart';
import 'container/container_manager.dart';
import 'observers_holders.dart'; import 'observers_holders.dart';
export 'container/boost_container.dart'; export 'container/boost_container.dart';
export 'container/container_manager.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( typedef PrePushRoute = Route<T> Function<T>(String url, String uniqueId,
String url, String uniqueId, Map params, Route route); Map<String, dynamic> params, Route<dynamic> route);
typedef void PostPushRoute( typedef PostPushRoute = void Function(
String url, String uniqueId, Map params, Route route, Future result); String url,
String uniqueId,
Map<String, dynamic> params,
Route<dynamic> route,
Future<dynamic> result,
);
class FlutterBoost { class FlutterBoost {
FlutterBoost() {
ContainerCoordinator(_boostChannel);
}
static final FlutterBoost _instance = FlutterBoost(); 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 FlutterBoost get singleton => _instance;
static ContainerManagerState get containerManager => static ContainerManagerState get containerManager =>
_instance.containerManagerKey.currentState; _instance.containerManagerKey.currentState;
static void onPageStart() { final GlobalKey<ContainerManagerState> containerManagerKey =
WidgetsBinding.instance.addPostFrameCallback((_) { GlobalKey<ContainerManagerState>();
singleton.channel.invokeMethod<Map>('pageOnStart').then((Map pageInfo) { final ObserversHolder _observersHolder = ObserversHolder();
if (pageInfo == null || pageInfo.isEmpty) return; final BoostChannel _boostChannel = BoostChannel();
if (pageInfo.containsKey("name") && static void onPageStart() {
pageInfo.containsKey("params") && WidgetsBinding.instance.addPostFrameCallback((Duration _) {
pageInfo.containsKey("uniqueId")) { singleton.channel
.invokeMethod<Map<String, dynamic>>('pageOnStart')
.then((Map<String, dynamic> pageInfo) {
if (pageInfo?.isEmpty ?? true) {
return;
}
if (pageInfo.containsKey('name') &&
pageInfo.containsKey('params') &&
pageInfo.containsKey('uniqueId')) {
ContainerCoordinator.singleton.nativeContainerDidShow( 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( static TransitionBuilder init({
{TransitionBuilder builder, TransitionBuilder builder,
PrePushRoute prePush, PrePushRoute prePush,
PostPushRoute postPush}) { PostPushRoute postPush,
}) {
if (Platform.isAndroid) { if (Platform.isAndroid) {
onPageStart(); onPageStart();
} else if (Platform.isIOS) { } else if (Platform.isIOS) {
// TODO(AlexVincent525): 未解之谜
assert(() { assert(() {
() async { () async {
onPageStart(); onPageStart();
...@@ -90,9 +110,10 @@ class FlutterBoost { ...@@ -90,9 +110,10 @@ class FlutterBoost {
final BoostContainerManager manager = BoostContainerManager( final BoostContainerManager manager = BoostContainerManager(
key: _instance.containerManagerKey, key: _instance.containerManagerKey,
initNavigator: child, initNavigator: child as Navigator,
prePushRoute: prePush, prePushRoute: prePush,
postPushRoute: postPush); postPushRoute: postPush,
);
if (builder != null) { if (builder != null) {
return builder(context, manager); return builder(context, manager);
...@@ -106,94 +127,95 @@ class FlutterBoost { ...@@ -106,94 +127,95 @@ class FlutterBoost {
BoostChannel get channel => _boostChannel; BoostChannel get channel => _boostChannel;
FlutterBoost() { /// Register a default page builder.
ContainerCoordinator(_boostChannel);
}
///Register a default page builder.
void registerDefaultPageBuilder(PageBuilder builder) { void registerDefaultPageBuilder(PageBuilder builder) {
ContainerCoordinator.singleton.registerDefaultPageBuilder(builder); ContainerCoordinator.singleton.registerDefaultPageBuilder(builder);
} }
///Register a map builders /// Register a map builders
void registerPageBuilders(Map<String, PageBuilder> builders) { void registerPageBuilders(Map<String, PageBuilder> builders) {
ContainerCoordinator.singleton.registerPageBuilders(builders); ContainerCoordinator.singleton.registerPageBuilders(builders);
} }
Future<Map<dynamic, dynamic>> open(String url, Future<Map<String, dynamic>> open(
{Map<dynamic, dynamic> urlParams, Map<dynamic, dynamic> exts}) { String url, {
Map<dynamic, dynamic> properties = new Map<dynamic, dynamic>(); Map<String, dynamic> urlParams,
properties["url"] = url; Map<String, dynamic> exts,
properties["urlParams"] = urlParams; }) {
properties["exts"] = exts; final Map<String, dynamic> properties = <String, dynamic>{};
return channel.invokeMethod<Map<dynamic, dynamic>>('openPage', properties); properties['url'] = url;
properties['urlParams'] = urlParams;
properties['exts'] = exts;
return channel.invokeMethod<Map<String, dynamic>>('openPage', properties);
} }
Future<bool> close(String id, Future<bool> close(
{Map<dynamic, dynamic> result, Map<dynamic, dynamic> exts}) { String id, {
Map<String, dynamic> result,
Map<String, dynamic> exts,
}) {
assert(id != null); assert(id != null);
BoostContainerSettings settings = containerManager?.onstageSettings; final BoostContainerSettings settings = containerManager?.onstageSettings;
Map<dynamic, dynamic> properties = new Map<dynamic, dynamic>(); final Map<String, dynamic> properties = <String, dynamic>{};
if (exts == null) { exts ??= <String, dynamic>{};
exts = Map<dynamic, dynamic>();
}
exts["params"] = settings.params; exts['params'] = settings.params;
if (!exts.containsKey("animated")) { if (!exts.containsKey('animated')) {
exts["animated"] = true; exts['animated'] = true;
} }
properties["uniqueId"] = id; properties['uniqueId'] = id;
if (result != null) { if (result != null) {
properties["result"] = result; properties['result'] = result;
} }
if (exts != null) { if (exts != null) {
properties["exts"] = exts; properties['exts'] = exts;
} }
return channel.invokeMethod<bool>('closePage', properties); return channel.invokeMethod<bool>('closePage', properties);
} }
Future<bool> closeCurrent( Future<bool> closeCurrent({
{Map<String, dynamic> result, Map<String, dynamic> exts}) { Map<String, dynamic> result,
BoostContainerSettings settings = containerManager?.onstageSettings; Map<String, dynamic> exts,
if (exts == null) { }) {
exts = Map<String, dynamic>(); final BoostContainerSettings settings = containerManager?.onstageSettings;
} exts ??= <String, dynamic>{};
exts["params"] = settings.params; exts['params'] = settings.params;
if (!exts.containsKey("animated")) { if (!exts.containsKey('animated')) {
exts["animated"] = true; exts['animated'] = true;
} }
return close(settings.uniqueId, result: result, exts: exts); return close(settings.uniqueId, result: result, exts: exts);
} }
Future<bool> closeByContext(BuildContext context, Future<bool> closeByContext(
{Map<String, dynamic> result, Map<String, dynamic> exts}) { BuildContext context, {
BoostContainerSettings settings = containerManager?.onstageSettings; Map<String, dynamic> result,
if (exts == null) { Map<String, dynamic> exts,
exts = Map<String, dynamic>(); }) {
} final BoostContainerSettings settings = containerManager?.onstageSettings;
exts["params"] = settings.params; exts ??= <String, dynamic>{};
if (!exts.containsKey("animated")) { exts['params'] = settings.params;
exts["animated"] = true; if (!exts.containsKey('animated')) {
exts['animated'] = true;
} }
return close(settings.uniqueId, result: result, exts: exts); return close(settings.uniqueId, result: result, exts: exts);
} }
///register for Container changed callbacks /// Register for Container changed callbacks
VoidCallback addContainerObserver(BoostContainerObserver observer) => VoidCallback addContainerObserver(BoostContainerObserver observer) =>
_observersHolder.addObserver<BoostContainerObserver>(observer); _observersHolder.addObserver<BoostContainerObserver>(observer);
///register for Container lifecycle callbacks /// Register for Container lifecycle callbacks
VoidCallback addBoostContainerLifeCycleObserver( VoidCallback addBoostContainerLifeCycleObserver(
BoostContainerLifeCycleObserver observer) => BoostContainerLifeCycleObserver observer) =>
_observersHolder.addObserver<BoostContainerLifeCycleObserver>(observer); _observersHolder.addObserver<BoostContainerLifeCycleObserver>(observer);
///register callbacks for Navigators push & pop /// Register callbacks for [Navigator.push] & [Navigator.pop]
void addBoostNavigatorObserver(NavigatorObserver observer) => void addBoostNavigatorObserver(NavigatorObserver observer) =>
ContainerNavigatorObserver.boostObservers.add(observer); ContainerNavigatorObserver.boostObservers.add(observer);
} }
...@@ -24,10 +24,10 @@ ...@@ -24,10 +24,10 @@
import 'dart:ui'; import 'dart:ui';
class ObserversHolder { 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) { 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); set.add(observer);
_observers[T.toString()] = set; _observers[T.toString()] = set;
...@@ -40,5 +40,5 @@ class ObserversHolder { ...@@ -40,5 +40,5 @@ class ObserversHolder {
void cleanObservers<T>(T observer) => _observers[T.toString()]?.clear(); 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>{};
} }
...@@ -27,7 +27,6 @@ class Logger { ...@@ -27,7 +27,6 @@ class Logger {
print('FlutterBoost#$msg'); print('FlutterBoost#$msg');
return true; return true;
}()); }());
//print('FlutterBoost=>$msg');
} }
static void error(String msg) { static void error(String msg) {
......
...@@ -17,42 +17,7 @@ dev_dependencies: ...@@ -17,42 +17,7 @@ dev_dependencies:
sdk: flutter sdk: flutter
mockito: 4.1.1 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: flutter:
plugin: plugin:
androidPackage: com.idlefish.flutterboost androidPackage: com.idlefish.flutterboost
pluginClass: FlutterBoostPlugin 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
import 'package:flutter_boost/channel/boost_channel.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_boost/channel/boost_channel.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
...@@ -22,13 +23,12 @@ void main() { ...@@ -22,13 +23,12 @@ void main() {
response = null; response = null;
test('sendEvent successfully', () async { test('sendEvent successfully', () async {
Map msg1 = Map<dynamic,dynamic>(); final Map<String, dynamic> msg1 = <String, dynamic>{};
BoostChannel().sendEvent("name", msg1); BoostChannel().sendEvent('name', msg1);
Map msg = Map<dynamic,dynamic>();
msg["name"] = "name";
msg["arguments"] = msg1;
final Map<String, dynamic> msg = <String, dynamic>{};
msg['name'] = 'name';
msg['arguments'] = msg1;
expect( expect(
log, log,
...@@ -36,13 +36,10 @@ void main() { ...@@ -36,13 +36,10 @@ void main() {
); );
}); });
test('invokeMethod successfully', () async { test('invokeMethod successfully', () async {
Map msg = <dynamic,dynamic>{}; final Map<String, dynamic> msg = <String, dynamic>{};
msg["test"] = "test"; msg['test'] = 'test';
BoostChannel().invokeMethod<dynamic>("__event__1", msg); BoostChannel().invokeMethod<dynamic>('__event__1', msg);
// expect(e, isException);
expect( expect(
log, log,
...@@ -50,11 +47,10 @@ void main() { ...@@ -50,11 +47,10 @@ void main() {
); );
}); });
test('invokeListMethod successfully', () async { test('invokeListMethod successfully', () async {
Map msg = <dynamic,dynamic>{}; final Map<String, dynamic> msg = <String, dynamic>{};
msg["test"] = "test"; msg['test'] = 'test';
var bb = await BoostChannel().invokeListMethod<dynamic>("__event__1", msg); await BoostChannel().invokeListMethod<dynamic>('__event__1', msg);
expect( expect(
log, log,
...@@ -62,11 +58,10 @@ void main() { ...@@ -62,11 +58,10 @@ void main() {
); );
}); });
test('invokeMapMethod successfully', () async { test('invokeMapMethod successfully', () async {
Map msg = <dynamic,dynamic>{}; final Map<String, dynamic> msg = <String, dynamic>{};
msg["test"] = "test"; msg['test'] = 'test';
BoostChannel().invokeMapMethod<dynamic,dynamic>("__event__1", msg); BoostChannel().invokeMapMethod<dynamic, dynamic>('__event__1', msg);
expect( expect(
log, log,
...@@ -75,9 +70,9 @@ void main() { ...@@ -75,9 +70,9 @@ void main() {
}); });
test('invokeMapMethod successfully', () async { test('invokeMapMethod successfully', () async {
Map msg = <dynamic,dynamic>{}; final Map<String, dynamic> msg = <String, dynamic>{};
msg["test"] = "test"; msg['test'] = 'test';
BoostChannel().invokeMapMethod<dynamic,dynamic>("__event__1", msg); BoostChannel().invokeMapMethod<dynamic, dynamic>('__event__1', msg);
expect( expect(
log, log,
...@@ -86,22 +81,24 @@ void main() { ...@@ -86,22 +81,24 @@ void main() {
}); });
test('addEventListener successfully', () async { test('addEventListener successfully', () async {
Function test = BoostChannel().addEventListener( final VoidCallback test = BoostChannel().addEventListener(
"addEventListener", (String name, Map arguments) async => "test"); 'addEventListener',
print("xxx" + test.toString()); (String name, Map<String, dynamic> arguments) async => 'test',
);
print('xxx' + test.toString());
expect( expect(
test.toString(), test.toString(),
"Closure: () => Null", 'Closure: () => Null',
); );
}); });
test('addMethodHandler successfully', () async { test('addMethodHandler successfully', () async {
Function test = BoostChannel().addMethodHandler(( final VoidCallback test = BoostChannel().addMethodHandler(
MethodCall call) async => "test"); (MethodCall call) async => 'test',
);
expect( expect(
test.toString(), test.toString(),
"Closure: () => Null", 'Closure: () => Null',
); );
}); });
}); });
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.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'; import 'package:flutter_test/flutter_test.dart';
class FirstWidget extends StatelessWidget { class FirstWidget extends StatelessWidget {
...@@ -149,11 +149,11 @@ void main() { ...@@ -149,11 +149,11 @@ void main() {
); );
await tester.pumpWidget(widget); 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.tap(find.byKey(targetKey));
await tester.pump(Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
expect(exception, isInstanceOf<FlutterError>()); expect(exception, isInstanceOf<FlutterError>());
expect('$exception', expect('$exception',
......
...@@ -49,8 +49,8 @@ void main() { ...@@ -49,8 +49,8 @@ void main() {
testWidgets( testWidgets(
'obtain BoostPageRoute through the BoostPageRoute.of(context) method', 'obtain BoostPageRoute through the BoostPageRoute.of(context) method',
(WidgetTester tester) async { (WidgetTester tester) async {
dynamic boostPageRoute; BoostPageRoute<dynamic> boostPageRoute;
dynamic boostPageRouteFindByOfMethod; BoostPageRoute<dynamic> boostPageRouteFindByOfMethod;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -58,10 +58,11 @@ void main() { ...@@ -58,10 +58,11 @@ void main() {
boostPageRoute = BoostPageRoute<void>( boostPageRoute = BoostPageRoute<void>(
settings: settings, settings: settings,
builder: (BuildContext context) => Builder( builder: (BuildContext context) => Builder(
builder: (context) { builder: (BuildContext context) {
return FloatingActionButton( return FloatingActionButton(
onPressed: () { onPressed: () {
boostPageRouteFindByOfMethod = BoostPageRoute.of<dynamic>(context); boostPageRouteFindByOfMethod =
BoostPageRoute.of<dynamic>(context);
}, },
); );
}, },
...@@ -74,7 +75,7 @@ void main() { ...@@ -74,7 +75,7 @@ void main() {
await tester.tap(find.byType(FloatingActionButton)); 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 // The route obtained from the ancestor node through the `of` method should be the same BoostPageRoute
// as the originally created BoostPageRoute // as the originally created BoostPageRoute
...@@ -85,15 +86,15 @@ void main() { ...@@ -85,15 +86,15 @@ void main() {
'try to find BoostPageRoute through the BoostPageRoute.of(context) method, ' 'try to find BoostPageRoute through the BoostPageRoute.of(context) method, '
'but it doesn\'t exist, the method should throw an Exception', 'but it doesn\'t exist, the method should throw an Exception',
(WidgetTester tester) async { (WidgetTester tester) async {
dynamic contextCache; BuildContext contextCache;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
onGenerateRoute: (RouteSettings settings) { onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<dynamic>( return MaterialPageRoute<dynamic>(
settings: settings, settings: settings,
builder: (context) => Builder( builder: (BuildContext context) => Builder(
builder: (context) => FloatingActionButton( builder: (BuildContext context) => FloatingActionButton(
onPressed: () { onPressed: () {
contextCache = context; contextCache = context;
}, },
...@@ -104,7 +105,7 @@ void main() { ...@@ -104,7 +105,7 @@ void main() {
), ),
); );
await tester.tap(find.byType(FloatingActionButton)); 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); expect(() => BoostPageRoute.of<dynamic>(contextCache), throwsException);
}); });
...@@ -112,8 +113,8 @@ void main() { ...@@ -112,8 +113,8 @@ void main() {
testWidgets( testWidgets(
'obtain BoostPageRoute through the BoostPageRoute.tryOf(context) method', 'obtain BoostPageRoute through the BoostPageRoute.tryOf(context) method',
(WidgetTester tester) async { (WidgetTester tester) async {
dynamic boostPageRoute; BoostPageRoute<dynamic> boostPageRoute;
dynamic boostPageRouteFindByOfMethod; BoostPageRoute<dynamic> boostPageRouteFindByOfMethod;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -121,7 +122,7 @@ void main() { ...@@ -121,7 +122,7 @@ void main() {
boostPageRoute = BoostPageRoute<void>( boostPageRoute = BoostPageRoute<void>(
settings: settings, settings: settings,
builder: (BuildContext context) => Builder( builder: (BuildContext context) => Builder(
builder: (context) { builder: (BuildContext context) {
return FloatingActionButton( return FloatingActionButton(
onPressed: () { onPressed: () {
boostPageRouteFindByOfMethod = boostPageRouteFindByOfMethod =
...@@ -137,7 +138,7 @@ void main() { ...@@ -137,7 +138,7 @@ void main() {
); );
await tester.tap(find.byType(FloatingActionButton)); 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 // The route obtained from the ancestor node through the `tryOf` method should be the same BoostPageRoute
// as the originally created BoostPageRoute // as the originally created BoostPageRoute
...@@ -149,7 +150,7 @@ void main() { ...@@ -149,7 +150,7 @@ void main() {
'try to find BoostPageRoute through the BoostPageRoute.tryOf(context) method, ' 'try to find BoostPageRoute through the BoostPageRoute.tryOf(context) method, '
'but it doesn\'t exist, the method should return null', 'but it doesn\'t exist, the method should return null',
(WidgetTester tester) async { (WidgetTester tester) async {
dynamic boostPageRouteFindByOfMethod; BoostPageRoute<dynamic> boostPageRouteFindByOfMethod;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -157,7 +158,7 @@ void main() { ...@@ -157,7 +158,7 @@ void main() {
return MaterialPageRoute<dynamic>( return MaterialPageRoute<dynamic>(
settings: settings, settings: settings,
builder: (BuildContext context) => Builder( builder: (BuildContext context) => Builder(
builder: (context) { builder: (BuildContext context) {
return FloatingActionButton( return FloatingActionButton(
onPressed: () { onPressed: () {
boostPageRouteFindByOfMethod = boostPageRouteFindByOfMethod =
...@@ -172,7 +173,7 @@ void main() { ...@@ -172,7 +173,7 @@ void main() {
); );
await tester.tap(find.byType(FloatingActionButton)); await tester.tap(find.byType(FloatingActionButton));
await tester.pump(Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
expect(boostPageRouteFindByOfMethod, null); expect(boostPageRouteFindByOfMethod, null);
}); });
......
...@@ -6,9 +6,6 @@ import 'package:flutter_test/flutter_test.dart'; ...@@ -6,9 +6,6 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'package:flutter_boost/channel/boost_channel.dart'; import 'package:flutter_boost/channel/boost_channel.dart';
import 'package:flutter_boost/container/container_coordinator.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 { class MockBoostChannel extends BoostChannel implements Mock {
MethodHandler get testHandler => _testHandler; MethodHandler get testHandler => _testHandler;
...@@ -17,12 +14,14 @@ class MockBoostChannel extends BoostChannel implements Mock { ...@@ -17,12 +14,14 @@ class MockBoostChannel extends BoostChannel implements Mock {
MethodHandler _testHandler; MethodHandler _testHandler;
EventListener _testEventListener; EventListener _testEventListener;
@override
VoidCallback addEventListener(String name, EventListener listener) { VoidCallback addEventListener(String name, EventListener listener) {
_testEventListener = listener; _testEventListener = listener;
return super.addEventListener(name, listener); return super.addEventListener(name, listener);
} }
@override
VoidCallback addMethodHandler(MethodHandler handler) { VoidCallback addMethodHandler(MethodHandler handler) {
_testHandler = handler; _testHandler = handler;
return super.addMethodHandler(handler); return super.addMethodHandler(handler);
...@@ -31,26 +30,26 @@ class MockBoostChannel extends BoostChannel implements Mock { ...@@ -31,26 +30,26 @@ class MockBoostChannel extends BoostChannel implements Mock {
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec(); // const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
test('test onMethodCall', () async { test('test onMethodCall', () async {
// Initialize all bindings because defaultBinaryMessenger.send() needs a window. // Initialize all bindings because defaultBinaryMessenger.send() needs a window.
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
MockBoostChannel boostChannel = MockBoostChannel(); final MockBoostChannel boostChannel = MockBoostChannel();
ContainerCoordinator(boostChannel); ContainerCoordinator(boostChannel);
final Map arguments =<dynamic,dynamic> {}; final Map<String, dynamic> arguments = <String, dynamic>{};
arguments["pageName"] = "pageName"; arguments['pageName'] = 'pageName';
arguments["params"] = <dynamic,dynamic>{}; arguments['params'] = <dynamic, dynamic>{};
arguments["uniqueId"] = "xxxxx"; arguments['uniqueId'] = 'xxxxx';
MethodCall call = MethodCall('didInitPageContainer', arguments); final MethodCall call = MethodCall('didInitPageContainer', arguments);
try { try {
boostChannel.testHandler(call); boostChannel.testHandler(call);
} catch (e) { } catch (e) {
expect(e, isAssertionError); expect(e, isAssertionError);
} }
MethodCall call2 = MethodCall('willShowPageContainer', arguments); final MethodCall call2 = MethodCall('willShowPageContainer', arguments);
try { try {
boostChannel.testHandler(call2); boostChannel.testHandler(call2);
...@@ -58,7 +57,7 @@ void main() { ...@@ -58,7 +57,7 @@ void main() {
expect(e, isNoSuchMethodError); expect(e, isNoSuchMethodError);
} }
MethodCall call3 = MethodCall('didShowPageContainer', arguments); final MethodCall call3 = MethodCall('didShowPageContainer', arguments);
try { try {
boostChannel.testHandler(call3); boostChannel.testHandler(call3);
...@@ -66,7 +65,8 @@ void main() { ...@@ -66,7 +65,8 @@ void main() {
expect(e, isNoSuchMethodError); expect(e, isNoSuchMethodError);
} }
MethodCall call4 = MethodCall('willDisappearPageContainer', arguments); final MethodCall call4 =
MethodCall('willDisappearPageContainer', arguments);
try { try {
boostChannel.testHandler(call4); boostChannel.testHandler(call4);
...@@ -74,7 +74,7 @@ void main() { ...@@ -74,7 +74,7 @@ void main() {
expect(e, isNoSuchMethodError); expect(e, isNoSuchMethodError);
} }
MethodCall call5 = MethodCall('onNativePageResult', arguments); final MethodCall call5 = MethodCall('onNativePageResult', arguments);
try { try {
boostChannel.testHandler(call5); boostChannel.testHandler(call5);
...@@ -82,14 +82,14 @@ void main() { ...@@ -82,14 +82,14 @@ void main() {
expect(e, isNoSuchMethodError); expect(e, isNoSuchMethodError);
} }
MethodCall call6 = MethodCall('didDisappearPageContainer', arguments); final MethodCall call6 = MethodCall('didDisappearPageContainer', arguments);
try { try {
boostChannel.testHandler(call6); boostChannel.testHandler(call6);
} catch (e) { } catch (e) {
expect(e, isNoSuchMethodError); expect(e, isNoSuchMethodError);
} }
MethodCall call7 = MethodCall('willDeallocPageContainer', arguments); final MethodCall call7 = MethodCall('willDeallocPageContainer', arguments);
try { try {
boostChannel.testHandler(call7); boostChannel.testHandler(call7);
...@@ -97,35 +97,36 @@ void main() { ...@@ -97,35 +97,36 @@ void main() {
expect(e, isNoSuchMethodError); expect(e, isNoSuchMethodError);
} }
Map arg = <dynamic,dynamic>{'type': 'backPressedCallback'}; final Map<String, dynamic> arg = <String, dynamic>{
'type': 'backPressedCallback'
};
try { try {
boostChannel.testEventListener("lifecycle", arg); boostChannel.testEventListener('lifecycle', arg);
} catch (e) { } catch (e) {
expect(e, isNoSuchMethodError); expect(e, isNoSuchMethodError);
} }
final Map<String, dynamic> arg2 = <String, dynamic>{'type': 'foreground'};
Map arg2 = <dynamic,dynamic>{'type': 'foreground'};
try { try {
boostChannel.testEventListener("lifecycle", arg2); boostChannel.testEventListener('lifecycle', arg2);
} catch (e) { } catch (e) {
expect(e, isNoSuchMethodError); expect(e, isNoSuchMethodError);
} }
Map arg3 = <dynamic,dynamic>{'type': 'background'}; final Map<String, dynamic> arg3 = <String, dynamic>{'type': 'background'};
try { try {
boostChannel.testEventListener("lifecycle", arg3); boostChannel.testEventListener('lifecycle', arg3);
} catch (e) { } catch (e) {
expect(e, isNoSuchMethodError); expect(e, isNoSuchMethodError);
} }
Map arg4 = <dynamic,dynamic>{'type': 'scheduleFrame'}; final Map<String, dynamic> arg4 = <String, dynamic>{
'type': 'scheduleFrame'
};
try { try {
boostChannel.testEventListener("lifecycle", arg4); boostChannel.testEventListener('lifecycle', arg4);
} catch (e) { } catch (e) {
expect(e, isNoSuchMethodError); expect(e, isNoSuchMethodError);
} }
}); });
} }
This diff is collapsed.
import 'package:flutter_boost/container/container_manager.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_boost/flutter_boost.dart'; import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_boost/container/container_manager.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized(); 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 { try {
// FlutterBoost.singleton FlutterBoost.singleton.closeByContext(
// .registerDefaultPageBuilder((pageName, params, _) => Container()); null,
// FlutterBoost.singleton.addContainerObserver( result: <String, dynamic>{},
// (ContainerOperation operation, BoostContainerSettings settings) {}); exts: <String, dynamic>{},
// );
// FlutterBoost.singleton.addBoostContainerLifeCycleObserver( } catch (e) {
// (ContainerLifeCycle state, BoostContainerSettings settings) {}); expect(e, isNoSuchMethodError);
// }
// 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);
// }
// });
} }
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_boost/flutter_boost.dart'; import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_boost/container/container_coordinator.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'page_widgets.dart'; import 'page_widgets.dart';
import 'package:flutter_boost/container/container_coordinator.dart';
class MyApp extends StatefulWidget { class MyApp extends StatefulWidget {
@override @override
...@@ -15,14 +16,19 @@ class _MyAppState extends State<MyApp> { ...@@ -15,14 +16,19 @@ class _MyAppState extends State<MyApp> {
void initState() { void initState() {
super.initState(); super.initState();
FlutterBoost.singleton.registerPageBuilders({ FlutterBoost.singleton.registerPageBuilders(<String, PageBuilder>{
'embeded': (pageName, params, _) => EmbededFirstRouteWidget(), 'embeded': (String pageName, Map<String, dynamic> params, _) =>
'first': (pageName, params, _) => FirstRouteWidget(), EmbededFirstRouteWidget(),
'second': (pageName, params, _) => SecondRouteWidget(), 'first': (String pageName, Map<String, dynamic> params, _) =>
'tab': (pageName, params, _) => TabRouteWidget(), FirstRouteWidget(),
'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params), 'second': (String pageName, Map<String, dynamic> params, _) =>
'flutterPage': (pageName, params, _) { SecondRouteWidget(),
print("flutterPage params:$params"); '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); return FlutterRouteWidget(params: params);
}, },
...@@ -40,24 +46,33 @@ class _MyAppState extends State<MyApp> { ...@@ -40,24 +46,33 @@ class _MyAppState extends State<MyApp> {
} }
void _onRoutePushed( 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 { class TestBoostNavigatorObserver extends NavigatorObserver {
@override
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) { void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
print("flutterboost#didPush"); print('flutterboost#didPush');
} }
@override
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) { void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
print("flutterboost#didPop"); print('flutterboost#didPop');
} }
@override
void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) { void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) {
print("flutterboost#didRemove"); print('flutterboost#didRemove');
} }
@override
void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) { void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {
print("flutterboost#didReplace"); print('flutterboost#didReplace');
} }
} }
...@@ -72,7 +87,7 @@ void main() { ...@@ -72,7 +87,7 @@ void main() {
); );
//open firt page //open firt page
ContainerCoordinator.singleton ContainerCoordinator.singleton
.nativeContainerDidShow("first", <dynamic,dynamic>{}, "1000000"); .nativeContainerDidShow('first', <String, dynamic>{}, '1000000');
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
...@@ -80,7 +95,7 @@ void main() { ...@@ -80,7 +95,7 @@ void main() {
//open second page firt(1000000)->second(2000000) //open second page firt(1000000)->second(2000000)
ContainerCoordinator.singleton ContainerCoordinator.singleton
.nativeContainerDidShow("second", <dynamic,dynamic>{}, "2000000"); .nativeContainerDidShow('second', <String, dynamic>{}, '2000000');
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
...@@ -89,7 +104,7 @@ void main() { ...@@ -89,7 +104,7 @@ void main() {
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
//close sencod page firt(1000000) //close sencod page firt(1000000)
FlutterBoost.containerManager?.remove("2000000"); FlutterBoost.containerManager?.remove('2000000');
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
...@@ -97,7 +112,7 @@ void main() { ...@@ -97,7 +112,7 @@ void main() {
// second page ,but pageId is 2000001 firt(1000000)->second(2000001) // second page ,but pageId is 2000001 firt(1000000)->second(2000001)
ContainerCoordinator.singleton ContainerCoordinator.singleton
.nativeContainerDidShow("second", <dynamic,dynamic>{}, "2000001"); .nativeContainerDidShow('second', <String, dynamic>{}, '2000001');
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
...@@ -107,7 +122,7 @@ void main() { ...@@ -107,7 +122,7 @@ void main() {
//reopen firt page second(2000001)->firt(1000000) //reopen firt page second(2000001)->firt(1000000)
ContainerCoordinator.singleton ContainerCoordinator.singleton
.nativeContainerDidShow("first",<dynamic,dynamic> {}, "1000000"); .nativeContainerDidShow('first', <String, dynamic>{}, '1000000');
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
...@@ -117,7 +132,7 @@ void main() { ...@@ -117,7 +132,7 @@ void main() {
// reopen second page and pageId is 2000001 firt(1000000)->second(2000001) // reopen second page and pageId is 2000001 firt(1000000)->second(2000001)
ContainerCoordinator.singleton ContainerCoordinator.singleton
.nativeContainerDidShow("second", <dynamic,dynamic>{}, "2000001"); .nativeContainerDidShow('second', <String, dynamic>{}, '2000001');
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
...@@ -126,24 +141,18 @@ void main() { ...@@ -126,24 +141,18 @@ void main() {
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
//close firt(1000000) page second(2000001) //close firt(1000000) page second(2000001)
FlutterBoost.containerManager?.remove("1000000"); FlutterBoost.containerManager?.remove('1000000');
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
expect(find.text('Second'), findsOneWidget); expect(find.text('Second'), findsOneWidget);
// open second(2000003) // open second(2000003)
ContainerCoordinator.singleton ContainerCoordinator.singleton
.nativeContainerDidShow("second", <dynamic,dynamic>{}, "2000003"); .nativeContainerDidShow('second', <String, dynamic>{}, '2000003');
await tester.idle(); await tester.idle();
expect(find.text('Second'), findsOneWidget); expect(find.text('Second'), findsOneWidget);
}); });
} }
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment