Flutter 混合开发系列 包含如下:

  • 嵌入原生View-Android
  • 嵌入原生View-iOS
  • 与原生通信-MethodChannel
  • 与原生通信-BasicMessageChannel
  • 与原生通信-EventChannel
  • 添加 Flutter 到 Android Activity
  • 添加 Flutter 到 Android Fragment
  • 添加 Flutter 到 iOS

每个工作日分享一篇,欢迎关注、点赞及转发。

使用新引擎创建 FlutterFragment

添加 Flutter 到 Fragment 与添加 Activity 基本一样,如果添加到 Activity 满足需求,建议使用 Activity,因为 Activity 更加灵活和易于使用。

添加到 Fragment 代码:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) val fragment = FlutterFragment.createDefault()
supportFragmentManager
.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit()
}
}

activity_main 布局文件修改如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
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"
tools:context=".MainActivity"> <FrameLayout
android:id="@+id/fragment_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@+id/button"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳转"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>

红色区域就是 FlutterFragment 部分,这里大部分是 Android 原生的知识。

上面已经加载了 UI,但并不能一些交互和行为,通常情况下,需要将 Activity 的生命周期透传给 FlutterFragment:

class MainActivity : AppCompatActivity() {
override fun onPostResume() {
super.onPostResume()
flutterFragment!!.onPostResume()
} override fun onNewIntent(@NonNull intent: Intent) {
flutterFragment!!.onNewIntent(intent)
} override fun onBackPressed() {
flutterFragment!!.onBackPressed()
} override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String?>,
grantResults: IntArray
) {
flutterFragment!!.onRequestPermissionsResult(
requestCode,
permissions,
grantResults
)
} override fun onUserLeaveHint() {
flutterFragment!!.onUserLeaveHint()
} override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
flutterFragment!!.onTrimMemory(level)
}
}

初始化新引擎路由

指定引擎路由:

val fragment = FlutterFragment
.withNewEngine()
.initialRoute("one_page")
.build<FlutterFragment>() supportFragmentManager
.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit()

使用缓存引擎创建 FlutterFragment

上面的方式每一个 FlutterFragment 都会创建一个 FlutterEngine(Flutter 引擎),当然 FlutterFragment 也支持 缓存引擎,用法与 Activity 一样,在 MyApplication 启动引擎:

class MyApplication : Application() {
lateinit var flutterEngine: FlutterEngine override fun onCreate() {
super.onCreate()
flutterEngine = FlutterEngine(this)
flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
FlutterEngineCache
.getInstance()
.put("engine_id", flutterEngine) }
}

使用:

val fragment = FlutterFragment
.withCachedEngine("engine_id")
.build<FlutterFragment>() supportFragmentManager
.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit()

初始化缓存引擎路由

初始化缓存引擎的路由:

flutterEngine = FlutterEngine(this)

flutterEngine.navigationChannel.setInitialRoute("one_page")

flutterEngine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
FlutterEngineCache
.getInstance()
.put("engine_id", flutterEngine)

更改入门点

默认情况下,FlutterFragment 的 entrypoint(入口点)是 main() 函数,我们可以修改其 entrypoint,

val fragment = FlutterFragment
.withNewEngine()
.dartEntrypoint("newMain")
.build<FlutterFragment>()

main.dart 文件中添加 entrypoint(入口点):

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

void newMain()=> runApp(NewApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData( primarySwatch: Colors.blue,
),
routes: {
'one_page':(context){
return OnePage();
},
'two_page':(context){
return TwoPage();
}
},
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
} class NewApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData( primarySwatch: Colors.blue,
),
home: TwoPage()
);
}
}

newMain 即新的 entrypoint。

更改 FlutterFragment 的渲染模式

FlutterFragment 的渲染模式有两种:SurfaceView 和 TextureView,默认是 SurfaceView,SurfaceView 的性能比 TextureView 好,但其层次结构必须在最顶层或最底层,而且在 Android N之前的Android版本上,无法对 SurfaceView 进行动画处理,因为它们的布局和渲染与其他 View 层次结构不同步,因此要合理选择渲染模式,渲染模式设置方法如下:

val fragment = FlutterFragment
.withNewEngine()
.renderMode(RenderMode.texture)
.build<FlutterFragment>()

设置 FlutterFragment 透明

默认情况下,FlutterFragment 使用 SurfaceView 渲染不透明背景。对于Flutter未绘制的任何像素,背景均为黑色。由于性能原因,首选使用不透明背景进行渲染。 Android上具有透明的 Flutter 渲染会对性能产生负面影响。但是,有的时候需要其透明,显示其底下的 UI,因此,Flutter在 FlutterFragment 中支持设置为透明。

val fragment = FlutterFragment
.withNewEngine()
.transparencyMode(TransparencyMode.transparent)
.build<FlutterFragment>()

将按下放置在 FlutterFragment 的底下,

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
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"
tools:context=".MainActivity"> <Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳转"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/> <FrameLayout
android:id="@+id/fragment_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>

此时 FlutterFragment 的背景已经透明了,但运行时发现并没有透明,按钮也没有显示,这是因为 Flutter 本身没有设置透明,设置Flutter 透明:

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
backgroundColor: Colors.transparent,
...
);
}

交流

老孟Flutter博客(330个控件用法+实战入门系列文章):http://laomengit.com

欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:

【Flutter 混合开发】添加 Flutter 到 Android Fragment的更多相关文章

  1. 【Flutter 混合开发】添加 Flutter 到 Android Activity

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  2. Flutter混合开发:Android接入Flutter

    Flutter Google推出已经已经一年多了,单个 Flutter 项目的开发流程已经很成熟了.对与个人开发者来说使用 Flutter 开发一个跨平台的App挺有意思.但是对于现有的项目改造来说还 ...

  3. 【Flutter 混合开发】添加 Flutter 到 iOS

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  4. 【Flutter 混合开发】嵌入原生View-Android

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-IOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  5. 【Flutter 混合开发】嵌入原生View-iOS

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  6. 【Flutter 混合开发】与原生通信-MethodChannel

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  7. 【Flutter 混合开发】与原生通信-BasicMessageChannel

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  8. 【Flutter 混合开发】与原生通信-EventChannel

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  9. flutter 混合开发

    flutter 混合开发 https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps https://flutter.de ...

随机推荐

  1. 关于数学公式Markdown

    打开写博客(这都打不开就...) 再打开"选项". 选"启用数学公式支持"对(以后有用嘻嘻) 在默认编辑器里有Markdown选对. 然后就可以 \[\sum\ ...

  2. 使用VMware虚拟机安装RHEL7(RedHat Enterprise Linux7)步骤

    准备工具: 1.VMware Workstation 14 2.RedHat Enterprise Linux 7.0镜像文件 在虚拟机内设置操作系统的硬件标准 单击"创建新的虚拟机&quo ...

  3. 俯瞰 Java 服务端开发

    原文首发于 github ,欢迎 star . Java 服务端开发是一个非常宽广的领域,要概括其全貌,即使是几本书也讲不完,该文将会提到许多的技术及工具,但不会深入去讲解,旨在以一个俯瞰的视角去探寻 ...

  4. MySQL 5.7 InnoDB锁

    简介 参考https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-gap-locks. InnoDB引擎实现了标准的行级别 ...

  5. Linux驱动知识点

    # i2c_add_driver和i2c_new_device匹配后调用i2c_probe # 启动开发板,在超级终端中输入命令"cat /proc/misc"也可以查看对应的杂项 ...

  6. SQL实战——04. 查找所有已经分配部门的员工的last_name和first_name以及dept_no (一个逗号引发的血案)

    查找所有已经分配部门的员工的last_name和first_name以及dept_noCREATE TABLE `dept_emp` (`emp_no` int(11) NOT NULL,`dept_ ...

  7. DevOps元素周期表——1号元素 Gitlab

    DevOps元素周期表--1号元素 Gitlab GitLab 是由 GitLab Inc.开发,一款基于 Git 的完全集成的软件开发平台(fully integrated software dev ...

  8. 101 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 05 通过方法实现学生类与专业类关联——方案二

    101 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 05 通过方法实现学生类与专业类关联--方案二 本文知识点:通过方法实现学生类与 ...

  9. Azure内容审查器之羞羞图审查

    上一篇 Azure 内容审查器之文本审查我们已经介绍了如果使用Azure进行文字内容的审核.对于社区内容,上传的图片是否含有羞羞内容也是需要过虑的.但是最为一般开发者自己很难实现这种级别的智能识别.但 ...

  10. CSG:清华大学提出通过分化类特定卷积核来训练可解释的卷积网络 | ECCV 2020 Oral

    论文提出类特定控制门CSG来引导网络学习类特定的卷积核,并且加入正则化方法来稀疏化CSG矩阵,进一步保证类特定.从实验结果来看,CSG的稀疏性能够引导卷积核与类别的强关联,在卷积核层面产生高度类相关的 ...