Перенос реализации Android в приложение Flutter

#android #flutter #android-layout #kotlin #flutter-layout

#Android #flutter #android-макет #kotlin #flutter-layout

Вопрос:

У меня есть реализация действия с двумя камерами в качестве проекта Android Kotlin. Я хочу использовать ту же двойную камеру в flutter, поскольку у flutter нет библиотек для работы с двумя камерами.

Я пытался сделать это с помощью каналов платформы, но, как оказалось, каналы платформы предназначены только для передачи сообщений между flutter и родной платформой. Я не просто хочу передавать сообщения, я хочу, чтобы фрагмент / активность проекта Android включался в качестве виджета flutter, который я могу использовать везде, где захочу.

По сути, существует действие 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>

  

Комментарии:

1. Я никогда не делал этого раньше, но я не думаю, что это возможно, поскольку flutter отличается от Android. Он компилирует свой исходный код в собственный код Android, но также компилирует свою собственную структуру и другие функциональные возможности в собственный код Android. Похоже, это односторонняя компиляция.

2. Вы также можете сохранить свое приложение и добавить в него flutter. flutter.dev/docs/ development/ .

3. @Rolly это возможно для приложений Android, однако наше приложение уже является приложением flutter.

Ответ №1:

Вы могли бы попробовать сделать это с помощью PlatformView in flutter.

Вы можете преобразовать свои функции Android / ios в соответствующие им отдельные представления / контроллеры и добавить представление в дерево виджетов flutter с помощью AndroidView (Android) или UiKitView (iOS).

Представления платформы позволяют встраивать собственные представления в приложение Flutter, поэтому вы можете применять преобразования, клипы и прозрачность к собственному представлению из Dart. Это позволяет, например, использовать собственные карты Google из SDK для Android и iOS непосредственно в вашем приложении Flutter, используя представления платформы.

Вы можете обратиться к официальным документам PlatformView здесь

Ниже приведен пример с простым представлением Android:

Flutter:

 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 и реализуйте PlatformView его из плагина Android flutter

 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() {}
}
  

Создайте фабричный класс для указанного выше собственного класса view, реализовав 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);
  }
}
  

И, наконец, просто зарегистрируйте PlatformView в своем FlutterActivity классе:

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

Комментарии:

1. Для конкретного случая реализации с двумя камерами одного вида будет недостаточно. Нам также нужно записывать видео, изображения и делиться ими с помощью реализации flutter. Как вы думаете, как мы можем решить проблему в целом?

2. PlatformView также имеет обработчики обратного вызова канала платформы. А также вы можете использовать MethodChannel для передачи данных или вызывать методы с любой стороны кода, flutter или native. Вы также можете взглянуть на PlatformViewLink то, Что дает элементы управления жестами и т. Д. Для взаимодействия с другой стороной кода