搜了下全网 FlutterBoost教程大都还是老版本,所有有了这篇。
当前使用环境
FlutterBoost 4.2.1
Flutter 3.3.4
首先根据官方文章集成 FlutterBoost
接下来开始填坑之旅
坑一:
此段代码在使用中会报个什么map转换错误,具体忘了。。。
Map<String, Object> map = settings.arguments as Map<String, Object> ;
改为
Map<String, dynamic> map = settings.arguments as Map<String, dynamic>;
坑二:
此段代码当 routerMap[settings.name] 为 null 时,会报错:type 'Null' is not a subtype of type '(RouteSettings, String?) => Route<dynamic>' in type cast。
Route<dynamic> routeFactory(RouteSettings settings, String uniqueId) {
FlutterBoostRouteFactory func = routerMap[settings.name] as FlutterBoostRouteFactory;
return func(settings, uniqueId);
}
改为
Route<dynamic>? routeFactory(RouteSettings settings, String? uniqueId) {
FlutterBoostRouteFactory? func = routerMap[settings.name];
if (func == null) return null;
return func(settings, uniqueId);
}
坑三:
在原生启动flutter直接进入报错界面。为什么呢?因为找不到 initialRoute 对应的界面。
查看源码:
class FlutterBoostApp extends StatefulWidget {
FlutterBoostApp(
FlutterBoostRouteFactory routeFactory, {
Key? key,
FlutterBoostAppBuilder? appBuilder,
String? initialRoute,
///interceptors is to intercept push operation now
List<BoostInterceptor>? interceptors,
}) : appBuilder = appBuilder ?? _defaultAppBuilder,
interceptors = interceptors ?? <BoostInterceptor>[],
initialRoute = initialRoute ?? '/',
super(key: key) {
BoostNavigator.instance.routeFactory = routeFactory;
}
initialRoute 为 null 就给个 '/',
在官方代码中没有注册 '/' 对应的界面,也没有给 initialRoute 赋值。
所以解决方法有二。
法一:注册一个 '/' 对应的界面
Map<String, FlutterBoostRouteFactory> routerMap = {
'/': (RouteSettings settings, String? uniqueId) {
return MaterialPageRoute(
settings: settings,
builder: (_) {
return MyHomePage(
title: "主页",
);
});
},
。。。
};
法二:给 initialRoute 个已注册的值
return FlutterBoostApp(
routeFactory,
appBuilder: appBuilder,
initialRoute: 'mainPage',
);
使用 FlutterBoostActivity 和 FlutterBoostFragment 加载 flutter
改造前
FlutterBoost.instance().setup(this, new FlutterBoostDelegate() {
@Override
public void pushNativeRoute(FlutterBoostRouteOptions options) {
//这里根据options.pageName来判断你想跳转哪个页面,这里简单给一个
Intent intent = new Intent(FlutterBoost.instance().currentActivity(), YourTargetAcitvity.class);
FlutterBoost.instance().currentActivity().startActivityForResult(intent, options.requestCode());
}
@Override
public void pushFlutterRoute(FlutterBoostRouteOptions options) {
Intent intent = new FlutterBoostActivity.CachedEngineIntentBuilder(FlutterBoostActivity.class)
.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
.destroyEngineWithActivity(false)
.uniqueId(options.uniqueId())
.url(options.pageName())
.urlParams(options.arguments())
.build(FlutterBoost.instance().currentActivity());
FlutterBoost.instance().currentActivity().startActivity(intent);
}
}, engine -> {
});
改造后
FlutterBoost.instance().setup(this, new FlutterBoostDelegate() {
@Override
public void pushNativeRoute(FlutterBoostRouteOptions options) {
System.out.println("flutter to native requestCode:" + options.requestCode());
if ("go_to_NativeActivity1".equals(options.pageName())) {
Intent intent = new Intent(FlutterBoost.instance().currentActivity(), NativeActivity1.class);
FlutterBoost.instance().currentActivity().startActivityForResult(intent, options.requestCode());
} else if ("go_to_NativeActivity2".equals(options.pageName())) {
Map<String, Object> map = options.arguments();
Intent intent = new Intent(FlutterBoost.instance().currentActivity(), NativeActivity2.class);
intent.putExtra("data", (String) map.get("msg2222"));
FlutterBoost.instance().currentActivity().startActivity(intent);
}
}
@Override
public void pushFlutterRoute(FlutterBoostRouteOptions options) {
Intent intent = new FlutterBoostActivity.CachedEngineIntentBuilder(FlutterBoostActivity.class)
.backgroundMode(options.opaque() ? FlutterActivityLaunchConfigs.BackgroundMode.opaque : FlutterActivityLaunchConfigs.BackgroundMode.transparent)
.destroyEngineWithActivity(false)
.uniqueId(options.uniqueId())
.url(options.pageName())
.urlParams(options.arguments())
.build(FlutterBoost.instance().currentActivity());
if (options.requestCode() == 0) {
FlutterBoost.instance().currentActivity().startActivity(intent);
} else {
FlutterBoost.instance().currentActivity().startActivityForResult(intent, options.requestCode());
}
}
}, engine -> {
});
FlutterBoostActivity
String[] options = {"无返回值", "有返回值"};
new AlertDialog.Builder(this)
.setTitle("FlutterBoostActivity:原生启动 flutter ")
.setItems(options, (dialog, which) -> {
Map<String, Object> map = new HashMap<>();
map.put("data", System.currentTimeMillis() + " by FlutterBoostActivity");
FlutterBoostRouteOptions.Builder builder = new FlutterBoostRouteOptions.Builder()
.pageName("mainPage")
.opaque(false)
.arguments(map);
if (which == 0) {
map.put("hasResult", false);
} else if (which == 1) {
map.put("hasResult", true);
builder.requestCode(1000);
}
FlutterBoost.instance().open(builder.build());
}).show();
通过 FlutterBoost.instance().open(builder.build()); 启动会进入到
public void pushFlutterRoute(FlutterBoostRouteOptions options){...}
FlutterBoostFragment
boolean hasResult = getIntent().getBooleanExtra("hasResult", false);
Map<String, Object> map = new HashMap<>();
map.put("data", System.currentTimeMillis() + " by FlutterBoostFragment");
map.put("hasResult", hasResult);
flutterBoostFragment = new FlutterBoostFragment.CachedEngineFragmentBuilder()
.url("mainPage")
.urlParams(map)
.build();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.my_container, flutterBoostFragment)
.commit();
接下来是flutter部分
ElevatedButton(
child: const Text('退出当前页面,返回参数给上一个Native页面'),
onPressed: () {
// Navigator.of(context).pop({'retval' : 'I am from dart 11'});
BoostNavigator.instance.pop({'retval': 'I am from dart'});
},
)
ElevatedButton(
child: const Text('打开原生界面'),
onPressed: () {
BoostNavigator.instance
.push("go_to_NativeActivity1") // Native页面路由
.then((value) => showToast('from native retval:$value'));
},
)
ElevatedButton(
child: const Text('打开并传参给原生界面'),
onPressed: () {
BoostNavigator.instance.push(
"go_to_NativeActivity2",
withContainer: false,
arguments: {"msg2222": "hello,native boy"},
opaque: true,
);
},
)
ElevatedButton(
child: const Text('打开一个 flutter 界面'),
onPressed: () async {
final result = await BoostNavigator.instance.push('simplePage1',
withContainer: false, arguments: {"data": "hello,flutter boy"}, opaque: false);
/// withContainer为 false 时,也可以使用原生的 Navigator
// final result = await Navigator.of(context).pushNamed('simplePage1', arguments: {"data": "hello,flutter boy 1111"});
showToast(result);
},
)
ElevatedButton(
child: const Text('发送消息给 native'),
onPressed: () async {
BoostChannel.instance.sendEventToNative(
"flutter_to_native_event", {"msg5555555": "my ${DateTime.now().millisecondsSinceEpoch}"});
},
)