4bf618c32506

因为笔者本身主要从事是Android开发,所以很多角度都是作为一个Android开发者学习Flutter的角度出发,IOS或者H5的开发同学可以选择性阅读

目录

4bf618c32506

前言

如果我们目前的项目是Android的,但是接下来我们希望部分页面可以使用Flutter进行开发,甚至我们希望在Native页面中嵌入FlutterUI组件,那么我们该如何实现呢?

创建Flutter Module

假设你现在Android项目的目录的结构是这样的

xxx/flutter_hybrid/FlutterHybridAndroid

这时候如果你想创建一个Flutter模块,使得Android模块和Flutter模块之间可以进行交互,我们可以通过Android Studio新建一个Flutter Module,具体过程是:File —> New —> New Module ,之后选择Flutter Module,指定Project Location的路径为

xxx/flutter_hybrid

也就是说,最终你的项目结构会是这样的

- flutter_hybrid

- flutter_module

- FlutterHybridAndroid

接下来在Android Module的build.gradle文件中添加flutter依赖

//FlutterHybridAndroid/app/build.gradle

...

dependencies {

implementation project(':flutter')

...

}

Android启动Flutter页面的两种方式

先创建一个Flutter页面

这里比较重要的是window.defaultRouteName这个字段,这个字段可以接收从Native传递过来的参数(下文我们会介绍原生传递参数的方法),也就是说通过这个字段我们就可以进行Flutter页面的路由的分发

import 'dart:ui';

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

title: 'FlutterHybird',

theme: ThemeData(

primarySwatch: Colors.blue,

),

//window.defaultRouteName可以接收从Native传过来的参数

home: _widgetForRoute(window.defaultRouteName),

);

}

}

Widget _widgetForRoute(String route) {

switch (route) {

case 'route1':

return Center(

child: Text("route1"),

);

case 'route2':

return Center(

child: Text("route2"),

);

default:

return Center(

child: Text('Unknown route: $route', textDirection: TextDirection.ltr),

);

}

}

直接启动一个FlutterActivity

我们可以直接在Android的MainActivity中启动一个FlutterActivity,这里的initialRoute方法中传递的参数就对应Flutter层的window.defaultRouteName

findViewById(R.id.jump).setOnClickListener(v -> {

startActivity(FlutterActivity.withNewEngine()

.initialRoute("route2")

.build(MainActivity.this));

});

注意:需要在AndroidManifest.xml注册FlutterActivity

android:name="io.flutter.embedding.android.FlutterActivity"

android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"

android:hardwareAccelerated="true"

android:windowSoftInputMode="adjustResize" />

启动复写后的FlutterActivity(推荐)

自己创建一个FlutterAppActivity继承自FlutterActivity

public class FlutterAppActivity extends FlutterActivity {

public final static String INIT_PARAMS = "initParams";

private String initParams;

public static void start(Context context, String initParams) {

Intent intent = new Intent(context, FlutterAppActivity.class);

intent.putExtra(INIT_PARAMS, initParams);

context.startActivity(intent);

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

initParams = getIntent().getStringExtra(INIT_PARAMS);

}

/**

* 重载该方法来传递初始化参数

*

* @return

*/

@NonNull

@Override

public String getInitialRoute() {

return initParams == null ? super.getInitialRoute() : initParams;

}

}

在MainActivity中启动FlutterAppActivity(另外别忘了在AndroidManifest.xml中注册FlutterAppActivity)

findViewById(R.id.jump).setOnClickListener(v -> {

FlutterAppActivity.start(MainActivity.this,"route2");

});

两种启动方式的区别

如果单纯只是想打开一个Flutter页面,两种方式实际上基本没有太大区别,第一种方式也许还会更简单一点。但是,在Flutter开发中,我们往往还需要开发一些Native插件供Flutter调用,如果使用复写FlutterActivity的方式更有利于我们在FlutterActivity中注册我们的Native插件,所以实际开发中一般推荐使用第二种方式

扩展思考

initialRoute从名称上看起来是Flutter提供给我们进行Native与Flutter交互的路由跳转的,但是实际上他就是一个字符串,我们不仅仅可以传递一个路由名称,有时候我们也可以通过这个参数传递一串JSON数据,然后在Flutter端进行解析,这样我们就可以通过这个参数做更多的事情

在Android原生页面中嵌入FlutterUI组件

activity_main.xml

FrameLayout用于承载Flutter组件

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context=".MainActivity">

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_weight="1"

android:background="@color/colorAccent"

android:gravity="center"

android:text="Hello World!" />

android:id="@+id/container"

android:layout_width="wrap_content"

android:layout_height="0dp"

android:layout_weight="1">

MainActivity.java

使用FragmentManager将FlutterFragment添加到FrameLayout容器中

FlutterFragment fragment = FlutterFragment.withNewEngine().initialRoute("route1").build();

getSupportFragmentManager()

.beginTransaction()

.replace(R.id.container, fragment)

.commit();

运行结果

上半部分是原生的TextView,下半部分是Flutter的Text组件

4bf618c32506

总结

本节主要介绍了Native和Flutter之间的页面跳转,以及同一个页面中Native与Flutter组件的组合。接下来会介绍如何编写Android插件与Flutter进行数据交互

android flutter 混合开发,Flutter(六)Android与Flutter混合开发(Hybird)相关推荐

  1. 星云链智能合约开发(六):智能合约开发与部署

    编写智能合约 Nebulas实现了NVM虚拟机来运行智能合约,NVM的实现使用了JavaScript V8引擎,所以当前的开发版,我们可以使用JavaScript.TypeScript来编写智能合约. ...

  2. 【Flutter】Flutter 开发环境搭建 ( Android Studio 下 Flutter / Dart 插件安装 | Flutter SDK 安装 | 环境变量配置 | 开发环境检查 )

    文章目录 一.Flutter 学习资料 二.Flutter 开发环境搭建 三.Android Studio 环境安装 Flutter / Dart 插件 四.下载 Flutter SDK 五.设置 F ...

  3. Android开发必会技术!Flutter中网络图片加载和缓存源码分析,完整PDF

    起因 事情是这样的. 4年前毕业那会,呆在公司的短视频项目,做 视频.那会做得比抖音还早,但是由于短视频太烧钱了,项目被公司关掉了.当时需要开发横竖屏直播/异步视频的场景,就研究下了市场上的 app, ...

  4. Android开发之爱奇艺Flutter跨平台Hybrid实践

    爱奇艺开播助手 爱奇艺开播助手项目,又称"直播机",该项目目标是通过一个移动平台为主播提供多样化的直播内容.现阶段所涵盖的直播内容包括:游戏直播,美女摄像直播,小剧场直播,其中游戏 ...

  5. 【错误记录】Flutter 混合开发报错 ( Android 端与 Flutter 端 EventChannel 初始化顺序错误导致无法通信 | EventChannel 通信流程 )

    文章目录 一. 报错信息 二. Android 端与 Flutter 端 EventChannel 注册与监听流程 三. 解决方案 一. 报错信息 在 Android 端初始化 EventChanne ...

  6. Flutter 与 原生交互(Android),关于Android开发的面试经验总结

    接收 */ void receiveMessage(){ messageChannel.setMessageHandler((message) async{ print(message); retur ...

  7. Flutter 与 原生交互(Android),安卓移动开发背景换色

    */ public static String CHANNEL = "com.mmd.flutterapp/plugin"; private static String ACTIO ...

  8. 【Flutter】手机应用类型 ( Android | iOS | Native 应用 | Web 应用 | Hybrid 应用 | ReactNative 应用 | Flutter 应用 )

    文章目录 一.Native 应用 二.Web 应用 三.Hybrid 应用 四.ReactNative 应用 五.Flutter 应用 一.Native 应用 原生应用开发 : Android / i ...

  9. 【Flutter】创建 Flutter 项目 ( Android Studio 创建并运行 Flutter 应用 | 命令行创建并运行 Flutter 应用 | 运行 Flutter 应用三种方式 )

    文章目录 一.Android Studio 中创建 Flutter 项目 二.命令行创建 Flutter 项目 三.通过命令行方式运行 Flutter 项目 四.通过 Android Studio 可 ...

  10. Flutter如何与Native(Android)进行交互

    目录 前言 BasicMessageChannel Android端- (1)不使用engine cache预热 (2)使用engine cache预热 Flutter端- MethodChannel ...

最新文章

  1. linux环境安全测评实验报告,linux第一次实验报告
  2. [转载] 财经郎眼20120409:证监会“百日维新”
  3. Java NIO之缓冲区
  4. python模拟登记获取cookie_Python爬虫实战入门四:使用Cookie模拟登录——获取电子书下载链接...
  5. usb禁止重定向_一种USB重定向处理方法和系统与流程
  6. Spring Boot 集成 Memcached
  7. 【金融申请评分卡】目标变量界定
  8. Illustrator 教程,如何在 Illustrator 中创建单线徽章?
  9. 【Oracle】交差并补
  10. 北大AI公开课笔记整理
  11. 复盘:企业微信中国发展简史
  12. 过滤多余的空格-C语言
  13. Openstack 使用Evacuate来实现HA
  14. 计算机科学的发展表情包,表情包发展简史
  15. 科技正渗透进你生活的全部
  16. IT前端开发和后端开发
  17. IP协议首部详细分析
  18. Autofill安装使用
  19. layui 输入框添加自定义图标
  20. J-Hi线下交流--实况

热门文章

  1. 安信可1.5---编译下载乐鑫ESP8266 RTOS SDK库
  2. Ubuntu18.04下安装Nvidia驱动和CUDA10.1+CUDNN7.6.5
  3. xampp php目录,htaccess文件,php,包括目录和Windows XAMPP配置噩梦
  4. SSRS中加入书签功能及数据集窗口
  5. matlab的fir1截止频率的设置
  6. 深挖Cerebras:世界上最大AI芯片的架构设计
  7. 什么是期权?如何从概念上理解看涨期权/看跌期权?
  8. idea:Build或Rebuild项目特别慢
  9. 路由器接口及连接(2)
  10. 前端优化系列之DNS预获取 dns-prefetch 提升页面载入速度