Evgenii Legotckoi
Evgenii Legotckoi6 марта 2018 г. 2:17

Android. Java vs Qt QML - Урок 005. Создаём контекстное меню

После того, как мы разобрались с тем, как создать меню в Action Bar, добавим контекстное меню к каким-нибудь объектам.

В данном уроке добавим два текстовых поля, которые будут иметь контекстное меню.

  • Контекстное меню первого текстового поля будет изменять цвет и размер текста в первом текстовом поле
  • Контекстное меню второго текстового поля будет просто изменять текст во втором текстовом поле.

Первое контекстное меню будет иметь два подменю, первое будет отвечать за изменение цвета, а второе будет отвечать за изменение размера.

ActionBar в Java активити отключим, чтобы он не мешался.


Внешний вид контекстных меню на Java

Внешний вид контекстных меню на Qt QML

Реализация на Java

activity_main.xml

В Активити создадим два текстовых поля с id:

  • firstTextView
  • secondTextView
<?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.javacontextmenu.MainActivity">

    <TextView
        android:id="@+id/firstTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="Use context menu to change my color and size"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/secondTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Use context menu to set text"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

MainActivity.java

Контекстное меню в Java будет создаваться через метод onCreateContextMenu.

Данные метод вызывается каждый раз перед вызовом контекстного меню. В данном методе меню заполняется всеми необходимыми пунктами меню в зависимости от того, для какого объекта вызывается данное контекстное меню.

Метод onCreateContextMenu содержит следующие аргументы:

  • ContextMenu , в который добавляются пункты меню
  • View - элемент экрана, для которого вызвано контекстное меню
  • ContextMenu.ContextMenuInfo – содержит доп.информацию, когда контекстное меню вызывается для элемента списка

Для обработки кликов по пунктам меню будет использоваться метод onContextItemSelected.

Для того, чтобы определить, как из пунктов меню был выбран, потребуется обозначить определённые id для каждого пункта меню, для этого воспользуемся переменными, обозначенными атрибутами final.

Для регистрации элементов интерфейса для обработки контекстного меню воспользуемся методом registerForContextMenu.

package com.evileg.javacontextmenu;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.Window;
import android.widget.TextView;

public class MainActivity extends Activity {

    TextView firstTextView;
    TextView secondTextView;

    // Context Menu of firstTextView
    final int MENU_COLORS = 1;
    final int MENU_SIZES = 2;

    final int COLOR_RED = 3;
    final int COLOR_GREEN = 4;
    final int COLOR_BLUE = 5;

    final int SIZE_24 = 6;
    final int SIZE_26 = 7;
    final int SIZE_28 = 8;
    final int SIZE_30 = 9;

    // Context Menu of secondTextView
    final int TEXT_1 = 10;
    final int TEXT_2 = 11;
    final int TEXT_3 = 12;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        // Найдём интересующие элементы интерфейса
        firstTextView = findViewById(R.id.firstTextView);
        secondTextView = findViewById(R.id.secondTextView);

        // Зарегистрируем их для контекстного меню
        registerForContextMenu(firstTextView);
        registerForContextMenu(secondTextView);
    }

    // Переопределим метод создания контекстного меню
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
    {
        // В зависимости от того, какое элемент интерфейса был выбран, создадим нужно контекстное меню
        switch (v.getId()) {
            case R.id.firstTextView:
                SubMenu colorsSubMenu = menu.addSubMenu(0, MENU_COLORS, 0, "Colors");
                colorsSubMenu.add(0, COLOR_RED, 0, "Red");
                colorsSubMenu.add(0, COLOR_GREEN, 0, "Green");
                colorsSubMenu.add(0, COLOR_BLUE, 0, "Blue");
                SubMenu sizesSubMenu = menu.addSubMenu(1, MENU_SIZES, 0, "Sizes");
                sizesSubMenu.add(1, SIZE_24, 0, "24");
                sizesSubMenu.add(1, SIZE_26, 0, "26");
                sizesSubMenu.add(1, SIZE_28, 0, "28");
                sizesSubMenu.add(1, SIZE_30, 0, "30");
                break;
            case R.id.secondTextView:
                menu.add(0, TEXT_1, 0, "Text 1");
                menu.add(0, TEXT_2, 0, "Text 2");
                menu.add(0, TEXT_3, 0, "Text 3");
                break;
        }
    }

    // Переопределим метод кликов по контекстному меню
    @Override
    public boolean onContextItemSelected(MenuItem item)
    {
        //
        switch (item.getItemId())
        {
            // Обработка пунктов меню первого контекстного меню
            case COLOR_RED:
                firstTextView.setTextColor(Color.RED);
                firstTextView.setText("Red color is setted");
                break;
            case COLOR_GREEN:
                firstTextView.setTextColor(Color.GREEN);
                firstTextView.setText("Green color is setted");
                break;
            case COLOR_BLUE:
                firstTextView.setTextColor(Color.BLUE);
                firstTextView.setText("Blue color is setted");
                break;
            case SIZE_24:
                firstTextView.setTextSize(24);
                firstTextView.setText("Size 24 is setted");
                break;
            case SIZE_26:
                firstTextView.setTextSize(26);
                firstTextView.setText("Size 26 is setted");
                break;
            case SIZE_28:
                firstTextView.setTextSize(28);
                firstTextView.setText("Size 28 is setted");
                break;
            case SIZE_30:
                firstTextView.setTextSize(30);
                firstTextView.setText("Size 30 is setted");
                break;
            // Обработка пунктов меню второго контекстного меню    
            case TEXT_1:
                secondTextView.setText("Text 1");
                break;
            case TEXT_2:
                secondTextView.setText("Text 2");
                break;
            case TEXT_3:
                secondTextView.setText("Text 3");
                break;
        }
        return super.onContextItemSelected(item);
    }
}

Реализация на QML

А вот вёрстка и обработка событий контекстных меню в QML будут реализованы в одном файле main.qml

main.qml

В данном случае для каждого текстового поля будет создан свой объект контекстного меню. Прямо в этих текстовых полях и разместим данное контекстное меню. Для создания меню потребуется соответствующий тип QML Menu.

Меню формируется древовидной структурой из объектов:

  • Menu - если требуется создание подменю
  • Action - действия, которые имеют сигнал triggered и обработчик onTriggered , к слову говоря, при разработке под Desktop , на эти Action можно навешать комбинации горячих клавиш.

В данном случае не понадобится присваивать различные id для пунктов меню, поскольку каждый Action имеет свой обработчик, просто пропишем для каждого свою собственную логику поведения. Обращение к свойствам текстовых полей производится через их id:

  • firstTextView
  • secondTextView
import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.3

ApplicationWindow {
    visible: true
    width: 360
    height: 520
    title: qsTr("QML Context Menu")

    Text {
        id: firstTextView
        font.pixelSize: 24
        text: qsTr("Use context menu to change my color and size")
        wrapMode: Text.Wrap

        anchors {
            top: parent.top
            topMargin: 24
            left: parent.left
            right: parent.right
        }

        // Область клика размещена на весь элемент Text для вызова контекстного меню
        MouseArea {
            anchors.fill: parent
            onPressAndHold: firstContextMenu.open()
        }

        Menu {
            id: firstContextMenu
            Menu {
                title: qsTr("Colors")
                Action {
                    text: qsTr("Red")
                    onTriggered: {
                        firstTextView.color = "red"
                        firstTextView.text = qsTr("Red color is setted")
                    }
                }
                Action {
                    text: qsTr("Green")
                    onTriggered: {
                        firstTextView.color = "green"
                        firstTextView.text = qsTr("Green color is setted")
                    }
                }
                Action {
                    text: qsTr("Blue")
                    onTriggered: {
                        firstTextView.color = "blue"
                        firstTextView.text = qsTr("Blue color is setted")
                    }
                }
            }
            Menu {
                title: qsTr("Sizes")
                Action {
                    text: qsTr("24")
                    onTriggered: {
                        firstTextView.font.pixelSize = 24
                        firstTextView.text = qsTr("Size 24 is setted")
                    }
                }
                Action {
                    text: qsTr("26")
                    onTriggered: {
                        firstTextView.font.pixelSize = 26
                        firstTextView.text = qsTr("Size 26 is setted")
                    }
                }
                Action {
                    text: qsTr("28")
                    onTriggered: {
                        firstTextView.font.pixelSize = 28
                        firstTextView.text = qsTr("Size 28 is setted")
                    }
                }
                Action {
                    text: qsTr("30")
                    onTriggered: {
                        firstTextView.font.pixelSize = 30
                        firstTextView.text = qsTr("Size 30 is setted")
                    }
                }
            }
        }
    }

    Text {
        id: secondTextView
        font.pixelSize: 24
        text: qsTr("Use context menu to set text")
        anchors.centerIn: parent

        // Область клика размещена на весь элемент Text для вызова контекстного меню
        MouseArea {
            anchors.fill: parent
            onPressAndHold: secondContextMenu.open()
        }

        Menu {
            id: secondContextMenu
            title: qsTr("Texts")
            Action {
                text: qsTr("Text 1")
                onTriggered: secondTextView.text = text
            }
            Action {
                text: qsTr("Text 2")
                onTriggered: secondTextView.text = text
            }
            Action {
                text: qsTr("Text 3")
                onTriggered: secondTextView.text = text
            }
        }
    }
}

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
d
  • dsfs
  • 26 апреля 2024 г. 14:56

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80баллов,
  • Очки рейтинга4
d
  • dsfs
  • 26 апреля 2024 г. 14:45

C++ - Тест 002. Константы

  • Результат:50баллов,
  • Очки рейтинга-4
d
  • dsfs
  • 26 апреля 2024 г. 14:35

C++ - Тест 001. Первая программа и типы данных

  • Результат:73баллов,
  • Очки рейтинга1
Последние комментарии
k
kmssr9 февраля 2024 г. 5:43
Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко5 февраля 2024 г. 12:50
Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 декабря 2023 г. 21:30
Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 декабря 2023 г. 19:38
Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik19 декабря 2023 г. 8:01
Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Сейчас обсуждают на форуме
G
Gar22 апреля 2024 г. 15:46
Clipboard Как скопировать окно целиком в clipb?
DA
Dr Gangil Academics20 апреля 2024 г. 17:45
Unlock Your Aesthetic Potential: Explore MSC in Facial Aesthetics and Cosmetology in India Embark on a transformative journey with an msc in facial aesthetics and cosmetology in india . Delve into the intricate world of beauty and rejuvenation, guided by expert faculty and …
a
a_vlasov14 апреля 2024 г. 16:41
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
Павел Дорофеев
Павел Дорофеев14 апреля 2024 г. 12:35
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
f
fastrex4 апреля 2024 г. 14:47
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

Следите за нами в социальных сетях