混合开发中不可避免的存在native向flutter页面跳转,flutter向原生跳转,甚至Activity或Fragment中某个view使用flutter开发。 咸鱼技术团队做为国内flutter技术领跑者开源了其混合栈的工具。 简书文章,或能够直接查阅GitHub仓库.android
鉴于hyBirdStacManager中含有一些咱们不很须要的功能和若干bug,目前咱们能够借鉴下思路写个简单的工具类。git
flutter开启原生页面并传参较为简单,能够经过官方methodChannel直接调用native方法,不在赘述github
class MyFlutterPlugin {
static const MethodChannel _channel =
const MethodChannel('com.your.packagename/flutter_plugin');
/**
* 打开原生页面
*/
static Future<String> openNativePage(String target , {Map paramsMap}) async {
if(paramsMap == null){
paramsMap = Map();
}
return await _channel.invokeMethod("openNative" , {"target" :target , "params" : paramsMap});
}
}
复制代码
参数的形式能够自定义为json,object等等json
注册插件的时机跟你的状况而定,如今先放在自动生成的插件后边bash
public abstract class BaseFlutterActivity extends FlutterFragmentActivity implements LifecycleOwner{
......
@Override
protected void onCreate(Bundle savedInstanceState) {
AppManager.getAppManager().addActivity(this);
......
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
//自定义plugin
MyPlugin.registerWith(getFlutterView());
}
}
public class MyPlugin {
public static void registerWith(final BinaryMessenger messenger){
new MethodChannel(messenger, "com.your.packagename/flutter_plugin").setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
....
// 解析参数,作页面跳转
if ("openNative".equals(methodCall.method)){
NativeRouteUtil.schemePage(methodCall,result);
}
}
});
}
}
跳转代码可参考伪代码
public static void schemePage(MethodCall methodCall, MethodChannel.Result result) {
String target = methodCall.argument("target");
switch (target) {
case FlutterConstant.ROUTE_NATIVE_SETTING:
SettingActivity.openSettingActivity(context);
break;
default:
break;
}
}
复制代码
这是很容易想到的思路,为了保证界面跳转动画统一,页面栈方便维护(即便是flutter栈),在每次渲染一个新flutter页面的时候给他一个原生的载体,即一个Activity的壳,在Activity中的flutterView加载flutter页面框架
flutter中有个main()方法入口,而且官方为咱们提供了入口route的获取方式less
void main(){
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_){
runApp(new MyApp());
});
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: _widgetForRoute(window.defaultRouteName),
);
}
}
Widget _widgetForRoute(String route) {
String uri = StringUtil.getSchemeRouteName(route);
String paramsJson = StringUtil.getSchemeRouteParams(route);
switch (uri) {
case ROUTE_ABOUT_US:
return AboutWidget(params: paramsJson);
default:
Toast.toast("您访问的页面不存在");
SystemNavigator.pop();
}
}
复制代码
_widgetForRoute(String route)方法的参数能够自行配置标准,能够为/path + ?+ params的形式,标记进入哪一个页面和传递相应参数。async
套壳是常见的封装形式,举个简单的例子,ide
public class FlutterContainerActivity extends BaseFlutterActivity {
public static void openFlutterContainerAct(Context context, String url) {
try {
Intent intent = new Intent(context, FlutterContainerActivity.class);
intent.putExtra(ROUTE_TARGET,url);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setAction(ROUTE_ACTION);
intent.addCategory(Intent.CATEGORY_DEFAULT);
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
复制代码
略.工具
不过能够封装一下,进入你的框架内,做为routeUtil的一部分
虽然flutter内部有官方的跳转方法,但假如你的根flutter页面做为tab嵌入的方式渲染的话,若是用 Navigator.of(context)跳转,会发生新页面没法全屏的现象,因此仍是为了动画统一和页面的良好管理机制,仍然推荐在dart内部先调用plugin方法,而后再用方式二进行跳转。
附dart内部的route跳转
class RouterUtil {
static const ROUTE = 1;
static const FADE = 2;
static route(BuildContext context, Widget targetWidget) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (mContext) => targetWidget));
}
static routeAnimation(BuildContext context, Widget targetWidget) {
Navigator.of(context)
.push(_MyCustomRoute(builder: (context) => targetWidget));
}
static route4Animation(BuildContext context, Widget targetWidget , num type) {
Navigator.of(context)
.push(_MyCustomRoute(builder: (context) => targetWidget , type : type));
}
}
class _MyCustomRoute<T> extends MaterialPageRoute<T> {
num mType = 2;
_MyCustomRoute({WidgetBuilder builder, RouteSettings settings , var type})
: super(builder: builder, settings: settings);
@override
Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
if (settings.isInitialRoute) return child;
if(mType == 1){
return RotationTransition(turns: animation, child: child);
}else if(mType == 2){
return FadeTransition(opacity: animation, child: child);
}
return FadeTransition(opacity: animation, child: child);
}
}
复制代码
前两天闲鱼放弃了以前的混合栈项目,新开源了flutter_boost , 这是github,有兴趣能够参考。