Флаттер мультиэкран с помощью DisplayManager или MediaRouter - PullRequest
0 голосов
/ 30 января 2020

Я разрабатываю приложение во Flutter, которое должно работать на POS с двумя экранами . По сути, это планшет, подключенный к другому экрану с помощью кабеля HDMI.

Моя проблема в том, что при работе на моя сторона экрана также отображается на экране клиента и мне нужно спрятать его и показать другой контент (например, рекламные акции).

Мне уже удалось использовать его, используя Android Presentation API (он будет работать только на Android). И я где-то читал, что я также могу добиться этого с помощью Media Router.

Но я хочу запустить два двигателя Flutter, по одному на каждом дисплее, или управлять тем, что отображается на каждом дисплее в флаттер. Проблема в том, что я не нашел ни одной библиотеки или полезной статьи о том, как это сделать на Flutter.

Кто-нибудь знает, как мне этого добиться? Если я не сделаю это, мне придется создать целый новый проект, используя нативный Android.

1 Ответ

0 голосов
/ 31 января 2020

Для тех, кто, возможно, сталкивается с этой проблемой, я наконец понял, как справиться с этим. Я все еще использую Android API представления , и сейчас я создаю новый движок для отображения клиента . Я решил это, используя FlutterView , который пока что довольно новый. Он в основном используется для рендеринга Flutter в приложении Native. Но в нашем случае он отобразит наш проект на другом экране.

Единственная проблема, которую я не решил (пока) - это то, что два движка - это совершенно разные приложения. Таким образом, если вы используете Provider для управления, например, состоянием своего приложения, у вас будет два или более экземпляра, по одному для каждого экземпляра, и изменения, внесенные в одном, не будут отражать другие.

В моем случае я решу это с помощью Socket.io, но вы, вероятно, также решите это с помощью Метод Канал . В идеале, он должен иметь только одно состояние, но сейчас вот что у меня есть.

Вот мой код для решения этой проблемы:

MainActivity.kt в Android / app / src / main / kotlin

package com.example.fsj_pdv

import android.content.Context
import android.hardware.display.DisplayManager
import android.os.Build
import android.os.Bundle
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setSecondDisplay()
    }

    private fun setSecondDisplay() {
        try {
            // Versions before Jelly Bean doesn't support it
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                val manager = applicationContext.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager

                // Busca os monitores disponíveis
                val displays = manager.displays

                // Verifica se foi encontrado mais de um monitor. Caso encontre, instancia a Activity de Presentation
                if (displays.size > 1) {
                    val display = displays[1]
                    val handler = PresentationHandler(this, display)
                    handler.show()
                }
            }
        } catch (e: Throwable) {
            println(e.message)
            e.printStackTrace()
        }
    }
}

И вот класс, который я создал, чтобы решить мою проблему (в той же папке). Цель этого класса в основном состоит в том, чтобы настроить наш дисплей презентации и выбрать представление контента, которое будет иметь наш FlutterView.

package com.example.fsj_pdv

import android.annotation.TargetApi
import android.app.Presentation
import android.content.Context
import android.os.Build
import android.os.Bundle
import android.view.Display
import io.flutter.embedding.android.FlutterView
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint


@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
class PresentationHandler(outerContext: Context?, display: Display?) : Presentation(outerContext, display) {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Instantiate a FlutterEngine.
        val flutterEngine = FlutterEngine(context)

        // Configure an initial route.
        flutterEngine.navigationChannel.setInitialRoute("/cliente")

        // Start executing Dart code to pre-warm the FlutterEngine.
        flutterEngine.dartExecutor.executeDartEntrypoint(DartEntrypoint.createDefault())

        setContentView(R.layout.presentation_view)

        val flutterView: FlutterView = findViewById(R.id.flutter_presentation_view)
        flutterView.attachToFlutterEngine(flutterEngine)
    }
}

Наконец, создайте простой макет, который будет отображать наше приложение в второй / внешний дисплей. Вот мой макет ( presentation_view. xml):

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

    <io.flutter.embedding.android.FlutterView
        android:id="@+id/flutter_presentation_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        />

</LinearLayout>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...