Wir implementieren also weiterhin die gleiche Funktionalität in Android-Anwendungen aus zwei grundlegend unterschiedlichen Welten. Nämlich in traditionellem Java und dem weniger verbreiteten Qt QML C++.
Diesmal implementieren wir das Menü in der ActionBar der Aktivität. Ich stelle fest, dass die ActionBar für die QML-Variante unabhängig geschrieben werden muss, da es in Qt QML kein solches Element gibt, es aber durch die ToolBar-Komponente implementiert wird. Da dieser Moment in der Lektion über Hello World beschrieben wurde, werden wir in dieser Lektion nicht näher darauf eingehen, wir werden ActionBar nur in eine separate QML-Datei aufnehmen, Machen Sie es zu einem separaten QML-Typ und fügen Sie ein Menüsymbol hinzu, indem Sie darauf klicken, auf das wir das Menü aufrufen.
Das Menü wird die folgende Struktur haben:
- Information
- Zuerst
- Zweitens
- Um
In der Mitte des Anwendungsfensters sollte sich Text befinden, der durch anderen Text ersetzt wird, wenn auf die folgenden Menüelemente geklickt wird
- Zuerst
- Zweite
- Um
Menüdarstellung in Java
Erste Ebene
Zweites Level
Darstellung des Menüs in Qt QML
Erste Ebene
Zweites Level
JAVA-Implementierung
menu.xml
Um das Menü zu gestalten, müssen Sie eine XML-Datei erstellen, die sich im Ressourcenverzeichnis des Menüs befindet. Nennen wir es also menu.xml
Hier ist alles ganz einfach, es gibt ein kleines Layout mit den Namen von Menüpunkten, verschachtelten Elementen und IDs, mit denen auf diese Elemente aus dem Java-Code zugegriffen werden kann.
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/informationItem" android:title="Information"> <menu> <item android:id="@+id/firstInfoItem" android:title="First" /> <item android:id="@+id/secondInfoItem" android:title="Second" /> </menu> </item> <item android:id="@+id/aboutItem" android:title="About" /> </menu>
activity_main.xml
Als nächstes kommt das Layout der Aktivität selbst, das in diesem Fall standardmäßig erstellt wird.
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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="com.evileg.javamenu.MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
MainActivity.java
Und jetzt müssen Sie alle Menükomponenten initialisieren und einen Click-Event-Handler an sie hängen.
package com.evileg.javamenu; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.TextView; public class MainActivity extends Activity { // Объявим объекты всех пунктов меню MenuItem aboutItem; MenuItem firstInfoItem; MenuItem secondInfoItem; // А также текстового поля, в которое будем устанавливать текст TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.textView); // найдём данное текстовое поле в ресурсах } // Создадим обработчики пунктов меню @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu, menu); // Найдём все элементы пунктов меню aboutItem = menu.findItem(R.id.aboutItem); firstInfoItem = menu.findItem(R.id.firstInfoItem); secondInfoItem = menu.findItem(R.id.secondInfoItem); // Создадим обработчик кликов по пунктам меню MenuItem.OnMenuItemClickListener onMenuClickListener = new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.aboutItem: textView.setText("About Menu Item is pressed"); break; case R.id.firstInfoItem: textView.setText("First Info Item is pressed"); break; case R.id.secondInfoItem: textView.setText("Second Info Item is pressed"); break; } return true; } }; // Установим этот обработчик на пункты меню aboutItem.setOnMenuItemClickListener(onMenuClickListener); firstInfoItem.setOnMenuItemClickListener(onMenuClickListener); secondInfoItem.setOnMenuItemClickListener(onMenuClickListener); return true; } }
Qt QML-Implementierung
ActionBar.qml
Ich habe einen benutzerdefinierten ActionBar-Typ in einer separaten QML-Datei erstellt, um ihn von der Hauptdatei main.qml zu trennen. Dadurch wird dieser Code vom Rest des nützlichen Codes getrennt, der den Unterschied zwischen Java- und Qt-QML-Menüimplementierungen zeigen sollte. Und auch diese ActionBar wird in den folgenden Artikeln verwendet.
Achten Sie auf das Signal menuClicked , dieses Signal wird in der ActionBar aufgerufen, wenn der Benutzer seinen Finger auf die MouseArea drückt, die für das Klicken auf unsere benutzerdefinierte Menüschaltfläche verantwortlich ist. Dieses Signal öffnet das Menü, das sich in der Datei main.qml befindet
import QtQuick 2.10 import QtQuick.Controls 2.3 import QtQuick.Controls.Material 2.1 ToolBar { id: root height: 48 signal menuClicked() // Сигнал, который сообщит о клике по кнопке меню Rectangle { anchors.fill: parent color: "#080808" Image { id: ico height: 36 width: 36 anchors { left: parent.left leftMargin: 10 top: parent.top topMargin: 6 } source: "qrc:/icons/ic_launcher.png" } Text { anchors { verticalCenter: parent.verticalCenter left: ico.right leftMargin: 4 } text: qsTr("QMLMenu") font.pixelSize: 18 color: "white" } // Начало реализации кнопки меню Rectangle { width: height color: menuArea.pressed ? "#55ffffff" : "transparent" anchors { top: parent.top right: parent.right bottom: parent.bottom } Image { id: menuIcon height: 36 width: 36 anchors { centerIn: parent } source: "qrc:/icons/menu.png" } MouseArea { id: menuArea anchors.fill: parent onClicked: root.menuClicked() } } // конец реализации кнопки меню } }
main.qml
Und hier wird der Code platziert, für den diese Lektion geschrieben wurde. Zeigen Sie, wie Sie das Menü selbst implementieren.
import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Controls 2.3 import QtQuick.Controls.Material 2.1 ApplicationWindow { id: root visible: true width: 360 height: 520 title: qsTr("QML Menu") // Добавляем ActionBar в окно приложения header: ActionBar { onMenuClicked: actionBarMenu.open() // Открываем меню // Добавляем меню Menu { id: actionBarMenu // С указанием расположения, чтобы Menu выскакивало в том же месте, // что и в варианте с Java x: root.width y: 48 Menu { title: qsTr("Information") Action { text: qsTr("First") // Обработка клика по меню onTriggered: label.text = qsTr("First Info Item is pressed") } Action { text: qsTr("Second") onTriggered: label.text = qsTr("Second Info Item is pressed") } } Action { text: qsTr("About") onTriggered: label.text = qsTr("About Menu Item is pressed") } } } Label { id: label anchors.centerIn: parent text: qsTr("Hello World!") font.pixelSize: 14 } }
Fazit
Natürlich gibt es einige Unterschiede in den Java- und Qt-QML-Standardmenüimplementierungen, wie z. B. das Vorhandensein eines Untermenütitels. Theoretisch kann dies in QML mit einer leeren Aktion implementiert werden, die einen Titel hat, leicht angepasst wird und beim Klicken nichts bewirkt, aber ist das notwendig?
Добрый день.
Как в такое меню добавить картинку и просто лэйблы с текстом?
И скажите пожалуйста как связаны ActionBar.qml и main.qml?
Превый файл скопировал, в другой qml вставил этот код, но меню не появляется
Вот так работает
У объектов MenuItem есть свойства iconName и iconSource. В iconSource можно добавить иконку из ресурсов в проекте. Можете воспользоваться этим свойством и тогда у вас будут в пунктах меню и иконки и текст.