【问题标题】:Transfer Android Implementation to Flutter Application将 Android 实现转移到 Flutter 应用程序
【发布时间】:2021-01-20 02:23:08
【问题描述】:

我有一个双摄像头活动的实现作为 Android Kotlin 项目。我想在颤振中使用相同的双摄像头,因为颤振没有任何用于双摄像头功能的库。

我曾尝试使用平台通道来做这件事,但事实证明平台通道只是用于颤振和原生平台之间的消息传递。我不只是想传递消息,我希望将一个 android 项目的片段/活动包含为一个颤振小部件,我可以在任何我想要的地方使用它。

基本上,有一个 Android 活动,其中有一些与之关联的 Kotlin 代码。我希望所有这些都在 Flutter 中工作并与之通信,包括 XML 前端和 Kotlin 后端。我在此处附上我的 xml 文件以供参考。代码文件只是填充 xml 组件。


<?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">

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:weightSum="2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <SurfaceView
            android:id="@+id/surfaceView2"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1.2" />

        <SurfaceView
            android:id="@+id/surfaceView"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_marginTop="-65dp"
            android:layout_weight="1" />
    </LinearLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:maxHeight="30dp"
            android:src="@drawable/ic_inclinedline"/>
    </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

【问题讨论】:

  • 我以前从未这样做过,但我认为这是不可能的,因为颤振与 android 不同。它确实将其源代码编译为原生 android 代码,但它也将自己的框架和其他功能编译为原生 android 代码。这似乎是一种单向编译。
  • 您也可以保留您的应用并为其添加 Flutter。 flutter.dev/docs/development/….
  • @Rolly 安卓应用是可能的,但是我们的应用已经是一个颤振应用了。

标签: android flutter android-layout kotlin flutter-layout


【解决方案1】:

您可以尝试在颤振中使用PlatformView

您可以将您的 android/ios 功能转换为各自独立的视图/控制器,并使用 AndroidView (Android) 或 UiKitView (iOS) 将视图添加到 Flutter 小部件树。

平台视图允许在 Flutter 应用中嵌入原生视图,因此您可以将变换、剪辑和不透明度应用到来自 Dart 的原生视图。例如,这允许您通过平台视图直接在 Flutter 应用中使用来自 Android 和 iOS SDK 的原生 Google 地图。

PlatformViewhere可以参考官方文档

以下是一个简单的 android 视图示例:

颤振:

Widget build(BuildContext context) {
  // This is used in the platform side to register the view.
  final String viewType = "NativeView";
  // Pass parameters to the platform side.
  final Map<String, dynamic> creationParams = <String, dynamic>{};

  return AndroidView(
    viewType: viewType,
    layoutDirection: TextDirection.ltr,
    creationParams: creationParams,
    creationParamsCodec: const StandardMessageCodec(),
  );
}

安卓: 在android上创建原生View类,并从android Flutter插件中实现PlatformView

class NativeView implements PlatformView {
   @NonNull private final TextView textView;

    NativeView(@NonNull Context context, int id, @Nullable Map<String, Object> creationParams) {
        textView = new TextView(context);
        textView.setTextSize(72);
        textView.setBackgroundColor(Color.rgb(255, 255, 255));
        textView.setText("Rendered on a native Android view (id: " + id + ")");
    }

    @NonNull
    @Override
    public View getView() {
        return textView;
    }

    @Override
    public void dispose() {}
}

通过实现PlatformViewFactory为上述原生视图类创建一个工厂类

class NativeViewFactory extends PlatformViewFactory {
  @NonNull private final BinaryMessenger messenger;
  @NonNull private final View containerView;

  NativeViewFactory(@NonNull BinaryMessenger messenger, @NonNull View containerView) {
    super(StandardMessageCodec.INSTANCE);
    this.messenger = messenger;
    this.containerView = containerView;
  }

  @NonNull
  @Override
  public PlatformView create(@NonNull Context context, int id, @Nullable Object args) {
    final Map<String, Object> creationParams = (Map<String, Object>) args;
    return new NativeView(context, id, creationParams);
  }
}

最后只需在 FlutterActivity 类中注册 PlatformView

public class MainActivity extends FlutterActivity {
    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        flutterEngine
            .getPlatformViewsController()
            .getRegistry()
            .registerViewFactory("NativeView", new NativeViewFactory());
    }
}

【讨论】:

  • 对于双摄像头实现的具体情况,只有一个视图是不够的。我们还需要录制视频、图像并通过 Flutter 实现共享它们。您认为我们可以如何解决完整的问题?
  • PlatformView 也有平台通道回调处理程序。您还可以使用MethodChannel 从代码的任一侧(颤动或本机)传递数据或调用方法。您还可以查看PlatformViewLink,它提供手势控制等以与代码的另一端进行交互
猜你喜欢
  • 2021-11-15
  • 1970-01-01
  • 2019-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-23
相关资源
最近更新 更多