Android工程内嵌Flutter

本文介绍如何在Android项目中嵌入Flutter页面,包括目录结构搭建、依赖引入、FlutterView创建及热加载支持等关键技术。

本文记录一下Android主工程中嵌入部分Fluttter页面的实现方法。

创建一个Android工程模拟你的现有工程

为了让Android工程和Flutter工程互不干扰,这里不再以Android工程为工程的跟目录,而是让Android工程和平级的Flutter工程的公共目录作为根目录。 最终的目录结构应该是下面这样的

你的项目根目录(随便什么你喜欢的地方)
  ├── 原生安卓工程(FlutterInAndroid)
  └── Flutter工程 (my_flutter)

所以首先在你的项目根目录下用AS创建一个新的Android原生项目,可以勾选上kotlin支持,这样更舒服。 创建完成后你会得到一个这样的结构

你的项目根目录(随便什么你喜欢的地方)
  └── FlutterInAndroid

FlutterInAndroid目录内是一个完整的Android工程

module模式创建Flutter工程

接下来使用Flutter命令来创建module工程,在你的项目根目录下执行:

flutter create -t module my_flutter
 

创建完成后你会得到一个这样的结构

你的项目根目录(随便什么你喜欢的地方)
  ├── FlutterInAndroid
  └── my_flutter

my_flutter是一个Flutter的module工程,用来供Android项目引入

在Android工程中引入依赖

在FlutterInAndroid这个Android工程的setting.gradle文件中追加flutter工程的引入
你的项目跟目录/FlutterInAndroid/setting.gradle

include ':app'
//加入下面配置
setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.parentFile,
        'my_flutter/.android/include_flutter.groovy'
))

 

在app的build.gradle文件中加入工程依赖
你的项目跟目录/FlutterInAndroid/app/build.gradle

...
dependencies {
    ...
    // 加入下面配置
    implementation project(':flutter')
}

 

使用AS打开FlutterInAndroid工程,重新构建项目,即可成功的将Flutter加入Android工程。

在Android工程中创建Flutter的View

Flutter提供了两种方式让Android工程来引用组件,一种是View,一种是Fragment,这里选用View来进行讲解,Fragment同理。 这里我们用两种方式来引入FLutter,本质是还是是作为一个view引入布局还是将FlutterView作为Activity的根View。

以单个view引入布局

val flutterView = Flutter.createView(this,lifecycle,"route1")

 

通过上面很简单的一个方法,我们就能通过Flutter创建出一个view,这个方法提供三个参数,第一个是Activity,第二个参数是一个Lifecycle对象,我们之间取Activity的lifecycle即可,第三个参数是告诉Flutter我们要创建一个什么样的view,这个字符串参数可以在Flutter工程中获取得到。
创建出这个FlutterView之后就可以按常规的操作来将它加入到任何你想要的布局中去了。

以根view作为Activity

创建一个空的Activity,用Flutter创建一个View作为页面的根View:

class FlutterActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_flutter)
        val flutterView = Flutter.createView(this@FlutterActivity,lifecycle,"route1")
        val layout = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
        addContentView(flutterView, layout)
    }
}

 

这里我们并没有使用setContentView而是是用了addContentView这个方法,原因是这样的:
虽然FLutter的加载速度非常快,但是这个过程依然存在,在创建FLutterView之前我们先给ContentView设置了一个R.layout.activity_flutter布局,这个布局可以作为FlutterView加载完成之前展示给用户的界面,当然大部分情况下用户根本感知不到这个界面Flutter已经加载完成了,但我们仍需要它,因为debug模式下造成Flutter的加载速度并不是非常快,这个界面可以给开发人员看,还有就是如果没有这个界面的话在Activity的加载过程会出现一个黑色的闪屏,而这个情况对用户来说并不友好。

在Flutter工程中根据不同的route创建不同的组件

用AndroidStudio在你的项目跟目录/my_flutter打开Flutter工程,这时候AndroidStudio插件会识别到Flutter工程并以Flutter工程进行加载。
忽略掉.android和.ios文件夹之后你会发现,这个FLutter工程和完整的Flutter工程并没有任何不同,你依然能够以完整Flutter工程的流程来进行Flutter开发并启动调试,这是一个非常人性化的设计。
上面我们在原生Android工程中以View的形式调用了Flutter,而Flutter本质上是只有一个入口的,也就是main.dart文件中的main函数:

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

 

我们的目的是根据原生工程的调用让Flutter生成不同的组件作为View来供原生工程使用,那么我们就可以从这个main函数来入手。
通过文档我们可以通过window的全局变量中获取到当前的routeName,这个值正是上面通过原生工程传给Flutter的标识,有了这个标识就可以简单的做判断来进行不同的组件创建了:

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

void main() => runApp(_widgetForRoute(window.defaultRouteName));

 


//根据不同的标识创建不同的组件给原生工程调用
Widget _widgetForRoute(String route) {
  switch (route) {
    case 'route1':
      return SomeWidget(...);
    case 'route2':
      return SomeOtherWidget(...);
    default:
      return Center(
        child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
      );
  }
}

 

让Flutter模块支持热加载

首先在Flutter目录下启动监听服务,在你的项目根目录/my_flutter下执行

flutter attach

 

执行后,监听服务会等待并监听debug应用中flutter的状态
然后在打开FlutterInAndroid项目的AS中以正常方式调试运行,在真机或模拟器中运行app后并不会立即出发flutter的监听服务,当flutter的view或Fragment激活时才会触发。
当flutter的监听服务和app建立连接后,终端会出现如下输出:

$ flutter attach -d W8
Waiting for a connection from Flutter on PLK UL00...
Done.
Syncing files to device PLK UL00...                          8.7s

?  To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R".
An Observatory debugger and profiler on PLK UL00 is available at: http://127.0.0.1:54218/
For a more detailed help message, press "h". To quit, press "q".

 

这时我们修改flutter工程中的dart代码文件,保存后在终端中点击r键即可进行热加载,R键进行热重启。

签名打包

引入flutter工程后,对Android原生工程的构建基本上没有影响,打包按常规操作即可。

Flutter创建的module工程中的Android工程与纯Flutter工程的中Android工程的比较

区别Flutter的module工程中的Android工程纯Flutter工程中的Android工程
文件夹名称.androidandroid
包含的moduleapp和Flutterapp
说明1app只提供了入口Activity,Flutter包含了插件扩展及原生工程调用的接口app包含入口Activity及插件扩展
说明2app供Flutter自身开发调试,Flutter作为module供Android原生调用app作为Android工程运行及打包

为了方便描述我们称前者为module工程,后者为完整工程。

由此可见,虽然module工程中提供了名为Flutter的module供原生工程调用,但仍然保留了app工程,这样非常大程度的方便了flutter工程师来单独开发flutter项目,无需依赖任何原生的调用,自身即可启动调试。

### 使用 Flutter 开发微信小程序 #### 项目概述 存在一个名为 flutter_weixin 的开源项目,该项目旨在通过模拟微信的用户界面来帮助开发者学习和掌握 Flutter 技术栈[^2]。 #### 学习目标 此项目不仅有助于理解如何利用 Flutter 实现复杂的交互逻辑,还能够指导开发者优化应用程序的 UI 设计。对于那些寻求高效创建图形化界面而不影响性能的应用团队来说,这是一个重要的参考资料。 #### 关键特性 - **高度仿真实验场**:提供完整的微信风格界面实现,成为练习 Flutter 界面设计的理想环境。 - **交互动画支持**:内嵌多种动画效果以及页面切换过渡特效,充分展示了 Flutter 提升用户体验的能力。 - **跨平台兼容性**:编写一次代码即可同时部署到 Android 和 iOS 平台,减少了开发工作量的同时保持了一致性的用户体验。 - **丰富的教育资源**:无论是初学者还是有经验的工程师都能从中受益匪浅,涵盖了从基础组件使用到高级状态管理和布局技巧等多个方面。 - **社区力量强大**:作为一个活跃于 GitHub 上的开源项目,拥有众多贡献者组成的社群网络,随时可以获得最新的技术支持和发展动态分享。 #### 获取教程与资源建议 虽然官方并没有直接针对“使用 Flutter 构建微信小程序”的专门文档,但是可以通过研究上述提到的 `flutter_weixin` 这样的案例来进行间接的学习。此外,在线平台上也有不少关于 Flutter 基础入门及进阶课程可供参考,比如: 1. 官方提供的 [Flutter 文档](https://flutter.dev/docs),这里包含了详细的 API 参考手册和技术指南; 2. YouTube 或 Bilibili 等视频网站上由个人博主上传的教学系列; 3. 各大技术论坛如 Stack Overflow 中有关解决特定问题的经验贴子; 值得注意的是,由于微信小程序本身基于 Web 技术栈(JavaScript/TypeScript, HTML/CSS),而 Flutter 是一套独立的技术体系,因此两者之间并不完全相同。如果目的是要真正意义上开发微信小程序,则应该关注 WeChat 官方提供的 SDK 和相关工具链[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值