Author: Сергей
Одно из нововведений в XE4 это платформонезависимый скроллинг.
С самого начала в Fire Monkey был компонент TScrollBox, который является предком для многих других компонентов (TListBox, TTreeView, TMemo и т.п.). Это контейнер который может содержать различные контролы, при этом они могут выходить далеко за границы видимой области TScrollBox.
На картинке изображается TScrollBox в RunTime и в DesignTime. Если упрощенно рассмотреть его структуру, то данный компонент (стилизованный контрол), содержит в себе полосы прокрутки и контрол ContentLayout обозначающий видимую область (на нижней картинке выделен темно-серым прямоугольником). Размеры ContentLayout соответствуют свойству ViewportSize для полос прокрутки.
На ContentLayout располагается контрол Content (содержимое ScrollBox`а). Когда мы бросаем какую-нибудь кнопку в TScrollBox, то она в реальности попадает в Content и когда мы перемещаем изображение внутри TScrollBox, на самом деле изменяются координаты Content.
Рассмотрим некоторые свойства:
-
- ViewportPosition — если говорить о физическом смысле, то это координаты левого верхнего угла видимой области на Content (см. зеленый текст). Эти координаты соответствую свойству Position для полос прокрутки. Сами полосы прокрутки VScrollBar и HScrollBar перенесены в раздел protected, поскольку это элементы стиля (строго говоря могут отсутствовать) и обращаться к ним надо осторожно.
-
- ContentBounds — границы, внутри которых располагаются все контролы (см. красный прямоугольник и текст). Эти координаты соответствуют свойствам Min и Max для полос прокрутки.
-
- OnViewportPositionChange — событие вызывается из виртуального метода ViewportPositionChange, после изменения координат, или размера видимой области.
-
- OnVScrollChange, OnHScrollChange — события вызываются при непосредственном перемещении ползунков на полосах прокрутки. Т.е. если мы меняем ViewportPosition или перетаскиваем содержимое мышью или пальцем, или содержимое перемещается по инерции, то эти события не срабатывают.
-
- OnCalcContentBounds — событие вызывается после рассчета нового значения ContentBounds, используя его мы можем изменить границы содержимого.
-
- AutoHide — если это свойство имеет значение True, то соответствующая полоса прокрутки скрывается когда размер ContentBounds меньше размера ContentLayout. В противном случае она становится недоступной.
-
- ShowScrollBars — если это свойство имеет значение False, то полосы прокрутки не видны ни когда, иначе они могут быть видны в зависимости от размеров, AutoHide, AutoShowing.
-
- ShowSizeGrip — это свойство разрешает отображение декоративного элемента, который располагается в правом нижнем углу окнон в Win-приложениях. На самом деле он виден если существует соответсвтующий элемент стиля и видны обе полосы прокрутки.
Если создавать наследника TScrollBox, то можно перекрыть виртуальные методы: HScrollChange, VScrollChange, ViewportPositionChange, DoCalcContentBounds вместо использования событий.
За плавное перемещение отвечает свойство AniCalculations
Вся логика отвечающая за поведение контрола при перетаскивании содержимого, вынесена в класс TAniCalculations который находится в модуле FMX.InertialMovement.
Свойство TScrollBox.AniCalculations создаётся с использованием виртуального метода CreateAniCalculations, перекрыв этот метод можно использовать свои классы для управления перемещением.
Умолчательное поведение скроллинга отличается на разлных платформах, узнать его можно с помощью функции GetScrollingBehaviours. Внутри виртуального метода TScrollBox.DoUpdateAniCalculations устанавливаются некоторые свойства AniCalculations по умолчанию. Вы можете перекрыть этот метод чтобы изменить умолчательные значения. Например:
procedure TVertScrollBox.DoUpdateAniCalculations(const AAniCalculations: TScrollCalculations);
begin
inherited DoUpdateAniCalculations(AAniCalculations);
AAniCalculations.TouchTracking := AAniCalculations.TouchTracking - [ttHorizontal];
end;
Изменить текущие значения свойств можно во время работы приложения, таким образом, к примеру, в Windows, можно заставить перемещаться содержимое по инерции, как это делается в iOS.
-
- Animation — разрешается перемещение по инерции.
-
- AutoShowing — разрешается плавное скрытие и показ полос прокрутки. Если это свойство имеет значение True, то скроллбыры обычно полностью прозрачны и не видны. Когда начинается движение они появляются, а после остановки плавно меняют прозрачность до 0. Просьба не путать со свойствами AutoHide и ShowScrollBars
-
- BoundsAnimation — разрешается перемещение содержимого за границы видимой обрасти, как на рисунке.
-
- TouchTracking — разрешается перетаскивание рабочей области с помощью мыши, или пальца по вертикали и по горизонтали (см. ttVertical, ttHorizontal).
-
- Averaging — это свойство несколько меняет логику работы. Когда происходит перемещение пальцем (ssTouch in Shift) это значение должно быть True.
-
- DecelerationRate — степень замедления, кода содержимое перемещается по инерции. Умолчательное значение DecelerationRateNormal = 1.95 примерно соответствует замедлению на родных приложениях iOS.
-
- Moved — это свойство указывает на то, что произошло перемещение, принимает значение False при выполнении метода MouseDown, и значение True в методе MouseMove, когда изменятся координаты. Если установлены свойства Averaging и Animation, то перемещение должно быть на расстояние больше DeadZone. Это на случай, если у пользователя с похмелья дрожат пальцы.
-
- Opacity — текущее значение прозрачности, используемое полосам прокрутки. См. AutoShowing.
-
- Down — это свойство указывает на то, что пользователь нажал кнопку мыши, или прикоснулся к сенсорному экрану.
Для начала пожалуй хватит…