混合開發中不可避免的存在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,有興趣能夠參考。