Evgenii Legotckoi
Evgenii Legotckoi4 января 2016 г. 21:41

QML - Урок 022. Анимация клика по элементу списка в стиле Material Design

QML не предоставляет анимацию взаимодействий кликов в стиле Material Design для Android по умолчанию, но это легко настраивается с помощью примитивов Rectangle. Анимация заключается в том, чтобы в одном родительском объекте Rectangle, при клике, необходимо второй дочерний объект Rectangle растянуть на всю область родительского. При этом дочерний объект будет растягиваться в течении определённого времени и выглядеть будет как расширяющийся круг, но при этом он не будет выходить за пределы родительского объекта.

Для наглядности создадим список элементов, по которым будем производить клики. Для отслеживания кликов будет использоваться область MouseArea, в которой будет отслеживаться несколько сигналов взаимодействия:

  • onClicked - в данном сигнале будет останавливаться анимация и выполняться результат взаимодействия со списком;
  • onPressed - при сигнале нажатия необходимо запустить анимацию, с предварительной установкой координат анимируемого объекта Rectangle.
  • onReleased - при отпускании элемента списка необходимо остановить анимацию;
  • onPositionChanged - при смене позиции области также необходимо остановить анимацию.

Для выполнения анимации используется объект PropertyAnimation. В данном объекте выбирается цель анимации, и список свойств, которые будут подвергаться изменению. В случае с анимируемым объектом Rectangl, необходимо расширять его как круг, для этого увеличиваем его свойства width, height и radius с одной и той же величиной. А для того, чтобы полностью заполнить родительский объект, выставим конечную величину свойств в три раза большую, чем ширина родительского элемента.

Также важным свойством родительского элемента является:

clip - активируя данное свойство ( true ), Мы обрезаем дочерние элементы объекта, чтобы они не выходили за границы родительского элемента.


Анимация клика - реализация в коде

import QtQuick 2.5
import QtQuick.Controls 1.4

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    /* Создадим список с несколькими элементами,
     * по которым будет производитсья анимированный клик
     * */
    ListView {
        anchors.fill: parent

        // В объекте находится ...
        delegate: Item {
            height: 48
            anchors.left: parent.left
            anchors.right: parent.right

            // ... прямоугольный фон,
            Rectangle {
                id: body
                anchors.fill: parent
                color: "white"
                // дочерние объекты будут обрезаться по области данного родительского элемента
                clip: true

                /* ... в котором находится другой фон, который будет
                 * анимированным кругом клика
                 * */
                Rectangle {
                    id: colorRect
                    height: 0
                    width: 0
                    color: "#e8e8e8"

                    /* Свойство трансформации, в котором будут пересчитываться
                     * стартовые координаты, чтобы был круг в центре клика
                     * */
                    transform: Translate {
                        x: -colorRect.width / 2
                        y: -colorRect.height / 2
                    }
                }

                // Надпись в элементе списка
                Text {
                    text: fragment
                    anchors.left: parent.left
                    anchors.leftMargin: 72
                    anchors.top: parent.top
                    anchors.bottom: parent.bottom
                    font.pixelSize: 14

                    renderType: Text.NativeRendering
                    horizontalAlignment: Text.AlignLeft
                    verticalAlignment: Text.AlignVCenter
                }

                // Область клика по элементу
                MouseArea {
                    anchors.fill: parent

                    onClicked: {
                        circleAnimation.stop()
                    }
                    onPressed: {
                        /* При нажатии на элемент выставляем стартовые координаты
                         * фона для анимации круга в элементе
                         * */
                        colorRect.x = mouseX
                        colorRect.y = mouseY
                        // Запускаем анимацию
                        circleAnimation.start()
                    }
                    onReleased: circleAnimation.stop()
                    onPositionChanged: circleAnimation.stop()
                }

                // Анимация свойств
                PropertyAnimation {
                    id: circleAnimation
                    target: colorRect   // Целью задаём круговой фон
                    properties: "width,height,radius" // В анимации изменяем высоту, ширину и радиус закругления
                    from: 0             // Изменяем параметры от о пикселей ...
                    to: body.width*3    // ... до тройного размера ширины элемента списка
                    duration: 300       // в течении 300 милисекунд

                    // По остановке анимации обнуляем высоту и ширину анимированного фона
                    onStopped: {
                        colorRect.width = 0
                        colorRect.height = 0
                    }
                }
            }
        }
        model: listModel
    }

    // Модель списка с элементами
    ListModel {
        id: listModel

        ListElement {fragment: qsTr("1-й Фрагмент")}
        ListElement {fragment: qsTr("2-й Фрагмент")}
        ListElement {fragment: qsTr("3-й Фрагмент")}
        ListElement {fragment: qsTr("4-й Фрагмент")}
        ListElement {fragment: qsTr("5-й Фрагмент")}
        ListElement {fragment: qsTr("6-й Фрагмент")}
        ListElement {fragment: qsTr("7-й Фрагмент")}
    }
}

Видеоурок

Результат анимации в стиле Material Design не является полностью идентичным тому, что должно быть, но показывает основную идею. Демонстрацию работы Вы можете увидеть в видеоуроке.

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

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

Комментарии

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

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

  • Результат:70баллов,
  • Очки рейтинга1
РК

Qt - Тест 001. Сигналы и слоты

  • Результат:84баллов,
  • Очки рейтинга4
ВМ

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

  • Результат:80баллов,
  • Очки рейтинга4
Последние комментарии
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" она решит проблему , лично мне помогло.
Сейчас обсуждают на форуме
NSProject
NSProject23 июня 2024 г. 23:48
добавить qlineseries в функции А куда собстаенно делся Евгений раз на сайте такой бордак творится?
BlinCT
BlinCT5 мая 2024 г. 15:46
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
Evgenii Legotckoi
Evgenii Legotckoi3 мая 2024 г. 0:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
IscanderChe
IscanderChe30 апреля 2024 г. 14:22
Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…
G
Gar22 апреля 2024 г. 15:46
Clipboard Как скопировать окно целиком в clipb?

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