Qt Quick für Android Studio-Projekte
Übersicht
Dieses Beispiel enthält ein QML-Projekt, das Sie mit dem Qt Tools for Android Studio-Plugin in Android Studio importieren können, sowie Java- und Kotlin-Projekte, die das QML-Projekt als Ansicht verwenden, indem sie die QtQuickView-API nutzen.
Weitere Informationen darüber, wie QML funktioniert, finden Sie in der Qt Qml. Diese Dokumentation wird sich darauf konzentrieren, wie eine QML-Komponente in Java- und Kotlin-basierte Android-Anwendungen eingebettet wird.
Zunächst schauen wir uns die MainActivity
's onCreate() Methode der Java- und Kotlin-Projekte an.
Für ein Java-basiertes Projekt:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); m_mainLinear = findViewById(R.id.mainLinear); m_getPropertyValueText = findViewById(R.id.getPropertyValueText); m_qmlStatus = findViewById(R.id.qmlStatusText); m_androidControlsLayout = findViewById(R.id.javaLinear); m_box = findViewById(R.id.qmlColorBox); m_switch = findViewById(R.id.disconnectQmlListenerSwitch); m_switch.setOnClickListener(view -> switchListener()); m_qtQuickView = new QtQuickView(this); // Set status change listener for m_qmlView // listener implemented below in OnStatusChanged m_mainQmlContent.setStatusChangeListener(this); m_secondQmlContent.setStatusChangeListener(this); ViewGroup.LayoutParams params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); m_qmlFrameLayout = findViewById(R.id.qmlFrame); m_qmlFrameLayout.addView(m_qtQuickView, params); m_qtQuickView.loadContent(m_mainQmlContent); Button m_changeColorButton = findViewById(R.id.changeQmlColorButton); m_changeColorButton.setOnClickListener(view -> onClickListener()); Button m_loadMainQmlButton = findViewById(R.id.loadMainQml); m_loadMainQmlButton.setOnClickListener(view -> loadMainQml()); Button m_loadSecondQmlButton = findViewById(R.id.loadSecondQml); m_loadSecondQmlButton.setOnClickListener(view -> loadSecondQml()); Button m_rotateQmlGridButton = findViewById(R.id.rotateQmlGridButton); m_rotateQmlGridButton.setOnClickListener(view -> rotateQmlGrid()); // Check target device orientation on launch handleOrientationChanges(); }
Für ein Kotlin-basiertes Projekt:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) m_binding = ActivityMainBinding.inflate(layoutInflater) val view = m_binding.root setContentView(view) m_binding.disconnectQmlListenerSwitch.setOnClickListener { switchListener() } m_qtQuickView = QtQuickView(this) // Set status change listener for m_qmlView // listener implemented below in OnStatusChanged m_mainQmlContent.setStatusChangeListener(this) m_secondQmlContent.setStatusChangeListener(this) val params: ViewGroup.LayoutParams = FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) m_binding.qmlFrame.addView(m_qtQuickView, params) m_qtQuickView!!.loadContent(m_mainQmlContent) m_binding.changeQmlColorButton.setOnClickListener { onClickListener() } m_binding.loadMainQml.setOnClickListener { loadMainQml() } m_binding.loadSecondQml.setOnClickListener { loadSecondQml() } m_binding.rotateQmlGridButton.setOnClickListener { rotateQmlGrid() } // Check target device orientation on launch handleOrientationChanges() }
Hinweis: Im Kotlin-Projekt verwenden wir View-Binding, um auf die UI-Komponenten der Anwendung zuzugreifen:
m_binding = ActivityMainBinding.inflate(layoutInflater) val view = m_binding.root setContentView(view)
Innerhalb der Methode onCreate()
wird eine zuvor deklarierte Variable m_qtQuickView
mit einer neuen QtQuickView initialisiert. Diese neue Instanz von QtQuickView wird erstellt, indem man ihr den Context der Java/Kotlin-Aktivität als Argument gibt.
Für ein Java-basiertes Projekt:
m_qtQuickView = new QtQuickView(this);
Für ein Kotlin-basiertes Projekt:
m_qtQuickView = QtQuickView(this)
Die Java-Klassen Main
und Second
erben von der Klasse QtQuickViewContent
. Diese Klassen werden aus dem von uns importierten QML-Projekt generiert. In diesem Beispiel werden diese QML-Komponenten verwendet, um zu erklären, wie QML-Komponenten in Android-Projekte eingebettet werden können.
Für ein Java-basiertes Projekt:
private final Main m_mainQmlContent = new Main(); private final Second m_secondQmlContent = new Second();
Für ein Kotlin-basiertes Projekt (initialisiert beim Deklarieren):
private var m_mainQmlContent: Main = Main() private val m_secondQmlContent: Second = Second()
Die m_mainQmlContent
wird über die Methode QtQuickView.loadContent()
, die QtQuickViewContent
als Argument erhält, in die m_qtQuickView
geladen.
Für ein Java-basiertes Projekt:
m_qtQuickView.loadContent(m_mainQmlContent);
Für ein Kotlin-basiertes Projekt:
m_qtQuickView!!.loadContent(m_mainQmlContent)
Die m_qtQuickView
wird der Android FrameLayout ViewGroup mit den entsprechenden Layout-Parametern hinzugefügt.
Für ein Java-basiertes Projekt:
ViewGroup.LayoutParams params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); m_qmlFrameLayout = findViewById(R.id.qmlFrame); m_qmlFrameLayout.addView(m_qtQuickView, params);
Für ein Kotlin-basiertes Projekt:
val params: ViewGroup.LayoutParams = FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) m_binding.qmlFrame.addView(m_qtQuickView, params)
Interaktion mit der QML-Komponente
Um mit der eingebetteten QML-Komponente zu interagieren, implementieren wir die Schnittstelle QtQmlStatusChangeListener
und überschreiben die Methode onStatusChanged, um den Ladestatus des QtQuickViewContent zu erhalten, der gerade in m_qtQuickView
geladen wird.
Für ein Java-basiertes Projekt:
public class MainActivity extends AppCompatActivity implements QtQmlStatusChangeListener{ ... }
Für ein Kotlin-basiertes Projekt:
class MainActivity : AppCompatActivity(), QtQmlStatusChangeListener{ ... }
Die onStatusChanged
Implementierung.
Für ein Java-basiertes Projekt:
@Override public void onStatusChanged(QtQmlStatus qtQmlStatus) { Log.i(TAG, "Status of QtQuickView: " + qtQmlStatus); final String qmlStatus = getResources().getString(R.string.qml_view_status) + m_statusNames.get(qtQmlStatus); // Show current QML View status in a textview m_qmlStatus.setText(qmlStatus); // Connect signal listener to "onClicked" signal from main.qml // addSignalListener returns int which can be used later to identify the listener if (qtQmlStatus == QtQmlStatus.READY && !m_switch.isChecked()) { m_qmlButtonSignalListenerId = m_mainQmlContent.connectOnClickedListener( (String name, Void v) -> { Log.i(TAG, "QML button clicked"); m_androidControlsLayout.setBackgroundColor(Color.parseColor( m_colors.getColor() )); }); } }
Für ein Kotlin-basiertes Projekt:
override fun onStatusChanged(status: QtQmlStatus?) { Log.v(TAG, "Status of QtQuickView: $status") val qmlStatus = (resources.getString(R.string.qml_view_status) + m_statusNames[status]) // Show current QML View status in a textview m_binding.qmlStatusText.text = qmlStatus // Connect signal listener to "onClicked" signal from main.qml // addSignalListener returns int which can be used later to identify the listener if (status == QtQmlStatus.READY && !m_binding.disconnectQmlListenerSwitch.isChecked) { m_qmlButtonSignalListenerId = m_mainQmlContent.connectOnClickedListener { _: String, _: Void? -> Log.i(TAG, "QML button clicked") m_binding.kotlinLinear.setBackgroundColor( Color.parseColor( m_colors.getColor() ) ) } } }
Der onStatusChanged
Listener wird als statusChangeListener
der m_mainQmlContent
und m_secondQmlContent
mit QtQuickViewContent.setStatusChangeListener(QtQmlStatusChangeListener onStatusChanged())
Methode eingestellt.
Für ein Java-basiertes Projekt:
m_mainQmlContent.setStatusChangeListener(this); m_secondQmlContent.setStatusChangeListener(this);
Für ein Kotlin-basiertes Projekt:
m_mainQmlContent.setStatusChangeListener(this) m_secondQmlContent.setStatusChangeListener(this)
Die überschriebene Callback-Funktion onStatusChanged()
empfängt das Signal StatusChanged()
, das den aktuellen Status (public Enum QtQmlStatus) des Ladens des aktuellen QtQuickViewContents in die m_qtQuickView
enthält. Wenn diese QtQmlStatus
als QtQmlStatus.READY
bestätigt wird, können wir mit der QML-Ansicht interagieren.
Laden von QtQuickViewInhalten in QtQuickView
Sie können mehrere QtQuickViewContents im importierten QML-Projekt haben und den aktuell geladenen Inhalt des QtQuickViews zwischen ihnen wechseln, indem Sie die Methode QtQuickView.loadContent() verwenden, die einen QtQuickViewContent als Argument annimmt. Damit wird der angegebene QtQuickViewContent geladen und der vorherige entladen, falls vorhanden.
Für ein Java-basiertes Projekt:
private void loadSecondQml() { m_qtQuickView.loadContent(m_secondQmlContent); // Reset box color and color text after component reload m_box.setBackgroundColor(Color.parseColor("#00ffffff")); m_getPropertyValueText.setText(""); } private void loadMainQml() { m_qtQuickView.loadContent(m_mainQmlContent); // Reset box color and color text after component reload m_box.setBackgroundColor(Color.parseColor("#00ffffff")); m_getPropertyValueText.setText(""); }
Für ein Kotlin-basiertes Projekt:
private fun loadSecondQml() { m_qtQuickView!!.loadContent(m_secondQmlContent) // Reset box color and color text after component reload m_binding.qmlColorBox.setBackgroundColor(Color.parseColor("#00ffffff")) m_binding.getPropertyValueText.text = "" } private fun loadMainQml() { m_qtQuickView!!.loadContent(m_mainQmlContent) // Reset box color and color text after component reload m_binding.qmlColorBox.setBackgroundColor(Color.parseColor("#00ffffff")) m_binding.getPropertyValueText.text = "" }
Abrufen und Setzen von Eigenschaftswerten von QML-Komponenten
Das Abrufen und Setzen von Eigenschaftswerten von QML-Komponenten erfolgt über die in der Klasse Main.java
beschriebenen Methoden. In diesem Fall verwenden wir die Methoden m_mainQmlContent.setColorStringProperty()
und m_mainQmlContent.getColorStringProperty()
. Diese Methoden werden je nachdem, welche Eigenschaften die QML-Komponente enthält, generiert.
Für ein Java-basiertes Projekt:
public void onClickListener() { // Set the QML view root object property "colorStringFormat" value to // color from Colors.getColor() m_mainQmlContent.setColorStringFormat(m_colors.getColor()); String qmlBackgroundColor = m_mainQmlContent.getColorStringFormat(); // Display the QML View background color code m_getPropertyValueText.setText(qmlBackgroundColor); // Display the QML View background color in a view // if qmlBackGroundColor is not null if (qmlBackgroundColor != null) { m_box.setBackgroundColor(Color.parseColor(qmlBackgroundColor)); } }
Für ein Kotlin-basiertes Projekt:
private fun onClickListener() { // Set the QML view root object property "colorStringFormat" value to // color from Colors.getColor() m_mainQmlContent.colorStringFormat = m_colors.getColor() val qmlBackgroundColor = m_mainQmlContent.colorStringFormat // Display the QML View background color code m_binding.getPropertyValueText.text = qmlBackgroundColor // Display the QML View background color in a view // if qmlBackgroundColor is not null if (qmlBackgroundColor != null) { m_binding.qmlColorBox.setBackgroundColor(Color.parseColor(qmlBackgroundColor)) } }
Mit der Methode m_mainQmlContent.setColorStringProperty()
setzen wir den Eigenschaftswert colorStringFormat
der Klasse m_mainQmlContent
auf einen zufälligen Farbwert, der aus der Klasse Colors.java
(oder Colors.kt
) geholt wird.
Die Methode m_mainQmlContent.getColorStringProperty()
wird hier verwendet, um die aktuelle Hintergrundfarbe des Root-Objekts des m_mainQmlContent zu holen und sie dann dem Benutzer auf der Java/Kotlin-Android-Seite der Anwendung anzuzeigen.
m_secondQmlContent
hat eine Grid QML-Komponente, die wir von der Java-Seite mit der generierten m_secondQmlContent.setGridRotation()
-Methode drehen können.
Für ein Java-basiertes Projekt:
private void rotateQmlGrid() { Integer previousGridRotation = m_secondQmlContent.getGridRotation(); if (previousGridRotation != null) { m_secondQmlContent.setGridRotation(previousGridRotation + 45); } }
Für ein Kotlin-basiertes Projekt:
private fun rotateQmlGrid() { val previousGridRotation = m_secondQmlContent.gridRotation if (previousGridRotation != null) { m_secondQmlContent.gridRotation = previousGridRotation + 45 } }
Signal-Listener
Die Klasse QtQuickViewContent
bietet die Methoden connectSignalListener()
und disconnectSignalListener()
, die zum Verbinden und Trennen von Signalhörern zwischen Signalen, die im Stammobjekt der QML-Komponente deklariert sind, verwendet werden. QtQuickViewContent.connectSignalListener()
gibt eine eindeutige Signal-Listener-ID zurück, die wir speichern und später verwenden, um den Listener zu identifizieren und die Verbindung zu trennen.
Hier verbinden wir einen Signal-Listener mit dem onClicked()
Signal der QML-Komponente.
Für ein Java-basiertes Projekt:
if (qtQmlStatus == QtQmlStatus.READY && !m_switch.isChecked()) { m_qmlButtonSignalListenerId = m_mainQmlContent.connectOnClickedListener( (String name, Void v) -> { Log.i(TAG, "QML button clicked"); m_androidControlsLayout.setBackgroundColor(Color.parseColor( m_colors.getColor() )); }); }
Für ein Kotlin-basiertes Projekt:
if (status == QtQmlStatus.READY && !m_binding.disconnectQmlListenerSwitch.isChecked) { m_qmlButtonSignalListenerId = m_mainQmlContent.connectOnClickedListener { _: String, _: Void? -> Log.i(TAG, "QML button clicked") m_binding.kotlinLinear.setBackgroundColor( Color.parseColor( m_colors.getColor() ) ) } }
Das Signal onClicked()
wird jedes Mal ausgegeben, wenn die Schaltfläche der QML-Komponente angeklickt wird. Dieses Signal wird dann von diesem Listener empfangen und die Hintergrundfarbe des Layouts, das die Android-Seite der Anwendung enthält, wird auf einen zufälligen Farbwert gesetzt, der aus der Klasse Colors.java
abgerufen wird.
Als nächstes wird der Signal-Listener mit der Methode QtQuickViewContent.disconnectSignalListener()
getrennt, indem ihm die eindeutige Signal-Listener-ID gegeben wird.
Für ein Java-basiertes Projekt:
m_mainQmlContent.disconnectSignalListener(m_qmlButtonSignalListenerId);
Für ein Kotlin-basiertes Projekt:
m_mainQmlContent.disconnectSignalListener(m_qmlButtonSignalListenerId)
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.