Источник: Блог Александра Божко
Одним из самых значимых и интересных новшеств в Deplhi XE7, безусловно, стал новый дизайнер форм FireUI Multi-Device Designer. Для того, что бы понять зачем он нужен и в чем заключается его ценность, нужно просто написать хотя бы одно Android приложение в Delphi XE5 или Delphi XE6, а затем запустить его на устройстве с другим формфактором. Вы сразу же поймете, что по сути, вы не сделали ничего и вам нужно "работать над интерфейсом". В подобную ситуацию я попал, создавая свое первое рабочее Android приложение. Отлаживал я его на планшете 7″, а демонстрировал на телефоне. Соответственно, и у меня и у приложения был весьма блеклый вид. А "работа над интерфейсом" вылилась не только в перетаскивание контролов, изменение их размеров и свойств. Пришлось писать код, высчитывать нужное положение и размеры элементов управления, в зависимости от размеров формы. Занятие трудоемкое. К тому же тестировать результаты приходилось на эмуляторе, что тоже добавляло сложностей.
В Delphi XE7 все изменилось радикальным образом. Если в двух словах, то теперь для каждого формфактора можно создать отдельный, наследуемый от основной формы, экземпляр формы. Боле того, учитывается не только размер экрана, но и платформа. Таким образом, если раньше мы говорили о единой кодовой базе для разных приложений, то теперь мы можем говорить об одном приложении для разных платформ. Все, что нам нужно - создать для каждой из форм набор представлений, позволяющий правильно отобразить форму на различных устройствах. При этом все это делается с помощью обычного интерфейса редактирования форм.
Давайте посмотрим, как же это выглядит на практике. Я не стану изобретать какие-то демонстрационные примеры, а попытаюсь показать все на примере рабочего (точнее разрабатываемого) приложения. Итак у нас есть некоторая форма. Изначально у нас выбрано представление Main.
Именно здесь мы и создаем базовый интерфейс программы, а так же пишем весь код, определяющий бизнес-логику. Если сейчас мы запустим программу под Windows, то она отработает как обычное десктопное FireMonkey приложение. В режиме проектирования формы левый выпадающий список (Style) отвечает за то, в каком стиле будут отображаться контролы на форме.
На рисунке видно как преобразится форма, если поменять стиль. Однако, все это работает только в режиме проектирования. Если вы запустите приложение в Windows - ничего не изменится, будут отображены обычные "виндовые" контролы. Точно так же, если вы соберете приложение под Android, будет задействован стиль Android. Если же принудительно указать стиль формы с помощью StyleBook, то контролы будут соответствовать стилю, выбранному в StyleBook и значение, выбранное в списке Style небудет учитываться при отображении формы.
Теперь давайте добавим два новых представления: Windows Desktop и Android 7″ Tablet. Для этого просто нужно выбрать их из секции Available списка Views.
Проведем небольшой эксперимент. Активируем в списке представление для Android и добавим на форму кнопку. Кнопка появится во всех представлениях, в том числе и в Master. Однако, если теперь мы сделаем кнопку невидимой (Visible = False) в Android, то в представлении для Windows и в Master представлении свойство Visible у кнопки не изменится. Соответственно, если запустить приложение в Windows, то кнопка будет видна, а вот под Android - нет.
Как это работает?
Если посмотреть, какие файлы были сгенерированы IDE для исследуемой формы, то помимо обычных <имя модуля>.pas и <имя модуля>.fmx появились еще два файла с составным именем.
Понятно, что они создаются для каждого их представлений. Таким образом, мы имеем единый класс формы для всех платформ, один базовый .fmx файл и по одному .fmx файлу для каждого представления. Компилятор сам определит какие ресурсы нужно включать в программу для каждой из платформ. Таким образом, мы действительно получаем один проект для разных платформ.
В Object Inspector можно очень быстро вернуть значение свойства компонента в исходное (т. е. совпадающие с Master представлением). Для этого нужно в контекстном меню выбрать пункт Revert to inherited.
Кстати, на мой взгляд было бы логичным иметь возможность "откатить" изменения всех свойств сразу.
Возможность сохранения значения свойств контролов отдельно для каждого из представлений открывает еще одну интересную возможность - назначать в каждом представлении собственные события.
Выберем представление Master и создадим обработчик нажатия кнопки, так как мы это обычно делаем в Delphi приложениях. После этого перейдем в представление Android 7″ Tablet и создадим для нажатия кнопки другой, новый обработчик. Для этого в Object Inspector вручную изменим название обработчика события onClick и дважды щелкнем по нему. Таким образом сгенерируем заготовку новой процедуры:
Как и следовало ожидать, при запуске приложения на планшете Android будет выводиться сообщение, отличное от того, которое выводится при запуске под Windows.
Естественно, что при работе с представлениями существуют и определенные ограничения. В частности, вы не сможете переименовать компонент в одном из представлений. Для того, что бы переименовать компонент, необходимо вернуться к представлению Master.
В заключении я бы хотел коснуться двух, возможно самых интересных в данном контексте, вопросов.
А что будет, если запустить приложение на устройстве, для которого не создано представление?
Насколько я понял англоязычную презентацию, умный компилятор попросту выберет наиболее близкое представление из имеющихся. Впрочем проверить это оказалось не сложно. В новом приложении на форму я поместил единственную кнопку и создал два представления, для Windows и для 10″ Android планшета. В представлении для планшета я поменял название кнопки и запустил приложение на планшете 7″. Как и следовало ожидать, при работе программы было использовано представление 10″ Android планшета.
Второй вопрос уже озвучивался неоднократно.
А можно ли сделать собственное представление для устройства, характеристики которого не представлены в списке доступных представлений?
Да, можно. О том как это сделать я расскажу в одном из следующих постов.
Интернет-магазин