如何使用带有自定义入口点的 FlutterFragment 在我的 Android 应用程序中嵌入 Flutter 布局?

How can I embed a Flutter layout in my Android App using FlutterFragment with a custom entry point?

我在 Flutter 中尝试的这个功能叫做 Add-to-App

我阅读了他们 documentation 中的说明,了解如何将 FlutterFragment 添加为我的应用中的一个部分。

如文档 example 中所示,我应该能够添加我的 newFlutterFragment 就像我在 Android 中添加普通 Fragment 类 一样.

// Create and attach a FlutterFragment if one does not exist.
if (flutterFragment == null) {
  var newFlutterFragment = FlutterFragment.createDefault()
  flutterFragment = newFlutterFragment
  fragmentManager
    .beginTransaction()
    .add(
      R.id.fragment_container,
      newFlutterFragment,
      TAG_FLUTTER_FRAGMENT
    )
    .commit()
}

我们的示例非常简单,但是,根据检查(Github 和 SO),它仅在您使用 预热 FlutterEngine 时有效main 默认入口点.

不幸的是,每当我尝试使用 自定义入口点 添加自己的 FlutterFragment 时,它似乎不接受我传入的对象类型FragmentTransaction.

.add(<INVALID_TYPE>,...,...) 方法

我是否仍然可以使用 FlutterFragment 作为我拥有的 Flutter 部分视图的容器?

设置

环境

哪里出了问题?

目前,如果您正在使用 AndroidX,您可以在嵌入 Flutter 布局时使用 FlutterFragment 的唯一方法是在您的依赖项中添加为 Android 存档 (AAR)

关于这个问题,我之前在 Github 中打开过一个 issue,在撰写本文时它仍然打开。

将 Flutter 添加为 AAR 依赖有利也有弊。使用 AAR,您的团队不需要在本地机器上安装 Flutter SDK,也不需要安装 Dart SDK。但是,由于 AAR 文件是编译后的工件,您的团队可能无法在开发过程中编辑项目的 Flutter 源代码。

Here's 有关如何使用添加为 AAR 模块的 Flutter 源代码设置 Android 项目的文档。

But why really use AAR?

在引擎盖下,FlutterFragment 和 类 的一些(如果不是全部) io.flutter.embedding 仍在使用支持库而不是 AndroidX,依赖项 不匹配 。使用 AAR 并在 编译 期间启用 jetifier,Flutter 的 AAR 输出现在将使用等效的 AndroidX 库,这是您不希望发生的事情运行时期间。

But, I need my team to work on some Flutter app features simultaneously with some Android app project changes.

好吧,由于您不能在该特定类型的设置中使用 FlutterFragment,您仍然可以使用 FlutterView,特别是如果您只在 Android应用

feature_fragment.kt

portfolioEngine?.let { flutterEngine ->
    // Start executing Dart code to pre-warm the FlutterEngine.
    // https://github.com/flutter/flutter/wiki/Experimental:-Launch-Flutter-with-non-main-entrypoint
    flutterEngine.dartExecutor.executeDartEntrypoint(
        DartExecutor.DartEntrypoint(
            FlutterMain.findAppBundlePath(),
            "customEntryPoint"
        )
    )

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

    // Add the Flutter layout
    flutterView = FlutterView(context)
    flutterView.attachToFlutterEngine(flutterEngine)
    flutterContainerView?.removeAllViews() // Only if deemed necessary
    flutterContainerView?.addView(flutterView)
}

feature_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/flutterContainerView"
        android:layout_width="match_parent"
        android:layout_height="300dp" />
</LinearLayout>

但是,有一个小问题...

FlutterView 相比,使用 FlutterActivityFlutterFragment 的好处之一是可以轻松地同时管理 Android 和 Flutter 代码的生命周期。别担心,您仍然可以通过使用附加的 FlutterEngine.

管理其生命周期来处理 Flutter 代码的行为方式

进一步阅读