© EVILEG 2015-2018
Рекомендует хостинг
TIMEWEB

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

Qt, Menu, JAVA, Android, QML

После того, как мы разобрались с тем, как создать меню в 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
            }
        }
    }
}

Комментарии

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
15 августа 2018 г. 19:02
Lord Inquisitoris

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

  • Результат 57баллов,
  • Очки рейтинга-2
15 августа 2018 г. 18:58
Lord Inquisitoris

C++ - Тест 005. Структуры и Классы

  • Результат 83баллов,
  • Очки рейтинга4
15 августа 2018 г. 9:29
Леха Завистович

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

  • Результат 86баллов,
  • Очки рейтинга6
Последние комментарии
10 августа 2018 г. 13:40
Alex

Работа с триггерными функциями в PostgreSQL

Приветствую! Если вы создаете новую таблицу, почему бы просто не сделать вьюху ? Просто от одного названия "триггер" как-то не хочется его использовать, а уж кода сколько писа...
10 августа 2018 г. 11:46
Евгений Легоцкой

Bash скрипт для создания и скачивания дампа базы данных и медиа файлов с удаленного сервера

Вон оно что. Не сталкивался с таким, надо будет глянуть исходники дефолтного менеджера объектов. Возможно там кеширование просто. Пробовали добавить запись через adminer, перезапусти...
10 августа 2018 г. 11:34
Alex

Bash скрипт для создания и скачивания дампа базы данных и медиа файлов с удаленного сервера

допустим у нас есть любая таблица, созданная джангой. через админку добавляем пару записей. все ок. далее, лично в моем случае , я открываю adminer, и в эту таблицу добавляю еще одну зап...
Сейчас обсуждают на форуме
15 августа 2018 г. 14:06
Олег Корнев

Как подключить QtCharts в QML?

После некоторых манипуляций (переустановил креатор) смог запустить экземплы с использованием QtCharts, но все они работают с подключениями в файлах .pro .cpp, у меня таких файлов нет. Как...
14 августа 2018 г. 7:02
Ruslan-maniak

Переключение страниц и перевод фокуса на потомка новой страницы

Большое спасибо. Подтолкнули меня на мысль вынести обработку клавиш из PathView на всю страницу. И тогда - да, ваша подсказка работает. добавил в StackView onCurrentItemChanged: currentItem.fo...
14 августа 2018 г. 6:39
Евгений Легоцкой

Как сделать аудиовизуализацию для плеера на qt?

Добрый день. Просмотрите пример в Qt Creator, который на QML, там реализовано визуализация, возможно вам понравится использовать, QML, да и кастомные интерфейсы на нём всё-таки лучше...
11 августа 2018 г. 10:12
Евгений Легоцкой

Qt C++ vs QML

Добрый день. Если Андроид предполагается, то конечно нужно использовать QML. Я занимался разработкой арканоида на QML и ещё одной игры. Пытался реализовывать логику на QML, но это ...
11 августа 2018 г. 9:24
Евгений Легоцкой

Помогите со слоями

Проверочное сообщение

Рекомендуемые страницы