【Flutter 混合开发】添加 Flutter 到 Android Fragment

【Flutter 混合开发】添加 Flutter 到 Android Fragment,第1张

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

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',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 透明:

@overrIDeWidget 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全部内容,希望文章能够帮你解决【Flutter 混合开发】添加 Flutter 到 Android Fragment所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1000436.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存