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 хостинг.

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

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Дмитрий

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

  • Результат:60баллов,
  • Очки рейтинга-1
Дмитрий

C++ - Тест 003. Условия и циклы

  • Результат:92баллов,
  • Очки рейтинга8
d
  • dsfs
  • 26 апреля 2024 г. 11:56

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

  • Результат:80баллов,
  • Очки рейтинга4
Последние комментарии
k
kmssr9 февраля 2024 г. 2:43
Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко5 февраля 2024 г. 9:50
Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 декабря 2023 г. 18:30
Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 декабря 2023 г. 16:38
Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik19 декабря 2023 г. 5:01
Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Сейчас обсуждают на форуме
G
George137 мая 2024 г. 7:27
добавить qlineseries в функции в функции: "GPlotter::addSeries(QString title, QVector &arr)" я вызываю метод setChart(...), я в конструктор передал адрес на QChartView элемент
BlinCT
BlinCT5 мая 2024 г. 12:46
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
PS
Peter Son4 мая 2024 г. 0:57
Best Indian Food Restaurant In Cincinnati OH Ready to embark on a gastronomic journey like no other? Join us at App india restaurant and discover why we're renowned as the Best Indian Food Restaurant In Cincinnati OH . Whether y…
Evgenii Legotckoi
Evgenii Legotckoi2 мая 2024 г. 21:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
IscanderChe
IscanderChe30 апреля 2024 г. 11:22
Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…

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