Flutter module接入安卓原生项目

引入flutter全局页面

基本步骤:
1.在android studio里打开你的安卓原生项目;
2.依次点击File->New->New Module,选择flutter module;
3.在AndroidManifest.xml文件中注册对应的FlutterActivity,具体配置如下:

<activity
  android:name="io.flutter.embedding.android.FlutterActivity"
  android:theme="@style/AppTheme"
  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
  android:hardwareAccelerated="true"
  android:windowSoftInputMode="adjustResize"
  />

4.从原生页面跳转到你的flutter页面:
*这里用一个按钮简单跳转,入口点是dart的main方法,flutter端路由默认为\,这里的currentActivity就是你原生页面对应的activity

myButton.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
    startActivity(
      FlutterActivity.createDefaultIntent(currentActivity)
    );
  }
});

在这里插入图片描述
(这里会有一段黑屏,是因为flutter engine有个初始化过程,此时不会进行渲染,后面会提到预热引擎的操作来解决这个问题)

*第二种场景是一个按钮从原生跳转到指定路由的flutter页面,getActivity()是你当前的原生页面所在的activity,这里指定跳转到一个欢迎页面
需要新建一个welcom_page.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class WelcomePage extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return _WelcomePageState();
  }
}

class _WelcomePageState extends State<WelcomePage>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("hello world!", style: TextStyle(color: Colors.red, fontSize: 32.0)),
      ),
    );
  }
}

需要配置路由

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttermodule/welcome_page.dart';

abstract class RouteSet {
  static const String WELCOME_PAGE = '/welcome';

}

//配置路由
final routes = {
  RouteSet.WELCOME_PAGE: (context) => WelcomePage(),
};

//固定写法
var onGenerateRoute = (RouteSettings settings) {
  final String name = settings.name;
  final Function pageContentBuilder = routes[name];
  if (pageContentBuilder != null) {
    if (settings.arguments != null) {
      final Route route = CupertinoPageRoute(
          settings: settings,
          builder: (context) =>
              pageContentBuilder(context, arguments: settings.arguments));
      return route;
    } else {
      final Route route = CupertinoPageRoute(
          settings: settings,
          builder: (context) => pageContentBuilder(context));
      return route;
    }
  }
};

需要在MaterialApp中注册路由跳转的回调方法

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
      onGenerateRoute: onGenerateRoute,
    );
  }
}

一个按钮从原生页面跳转到flutter指定页面

 myButton2.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
         startActivity(
                 FlutterActivity
                         .withNewEngine()
                         .initialRoute("/welcome")
                         .build(getActivity())
         );
     }
 });

在这里插入图片描述
5.为了解决上述的跳转黑屏现象,需要预热一个flutter引擎,预热的时机根据场景由读者自己决定,一般是在跳转flutter的原生页面入口处预热缓存这个引擎,my_engine_id由读者自定义

public class MyApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    // Instantiate a FlutterEngine.
    flutterEngine = new FlutterEngine(this);

    // Start executing Dart code to pre-warm the FlutterEngine.
    flutterEngine.getDartExecutor().executeDartEntrypoint(
      DartEntrypoint.createDefault()
    );

    // Cache the FlutterEngine to be used by FlutterActivity.
    FlutterEngineCache
      .getInstance()
      .put("my_engine_id", flutterEngine);
  }
}

在跳转处使用你预热的引擎

myButton.addOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
    startActivity(
      FlutterActivity
        .withCachedEngine("my_engine_id")
        .build(currentActivity)
      );
  }
});

此时,当你从原生页面跳转flutter页面时,延迟会好很多。

注意:
一、退出flutter页面后,要手动销毁flutterEngine,回收内存

 @Override
 public void onDestroy() {
     super.onDestroy();
     flutterEngine.destroy();
 }

二、在pre-warmed cached flutter engine中指定初始化路由:

 //determine a specific initial route
 flutterEngine.getNavigationChannel().setInitialRoute("/welcome");

三、在已经执行了dart的runApp()方法后,改变路由通道的初始路由属性,是没有效果的。开发者如果使用一个flutter engine在多个activites和fragments之间实现跳转,需要显式地申明一个method channel,然后手动去进行flutter路由跳转。

6.跳转到一个无背景的flutter页面,即无scaffold
定义一个风格

<style name="MyTheme" parent="@style/MyParentTheme">
  <item name="android:windowIsTranslucent">true</item>
</style>

引入这个风格到FlutterActivity

<activity
  android:name="io.flutter.embedding.android.FlutterActivity"
  android:theme="@style/MyTheme"
  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
  android:hardwareAccelerated="true"
  android:windowSoftInputMode="adjustResize"
  />

跳转的flutter页面是局部渲染的,例如

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class TransparentPage extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 100,
        height: 100,
        color: Colors.blueAccent,
      ),
    );
  }
}

跳转代码

startActivity(
        FlutterActivity
                .withCachedEngine("prewarmed_engine")
                .backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.transparent)
                .build(getActivity())
);

引入flutter局部页面(fragment)

to be continued

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值