уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Как я писал в одном из последних постов, библиотека FMX претерпела значительные изменения, «обросла» новыми возможностями и, в принципе, уже мало похожа на FireMonkey из Delphi XE2. И, чтобы снова вникнуть в работу с библиотекой, приходится изучать всё практически с нуля, начиная от просмотра демо-примеров из Delphi и, заканчивая поиском ответов на вопросы в различных форумах, посвященных работе в Delphi. На протяжении всего моего знакомства с новой версией библиотеки я буду делится с Вами найденными материалами на страницах блога webdelphi.ru. Это будут различные по объему и содержанию обзоры. Каждый обзор — работа с конкретным компонентом FMX — TListBox, TListView и так далее, начиная от рассмотрения демо-примеров и, заканчивая рассмотрением различных вопросов, которые возникают у разработчиков, использующих в своих проектах библиотеку FMX. В общем должны получится небольшие такие уроки по FireMonkey (FMX), которых, говорят, не хватает начинающим разработчикам.

Первый субботний обзор компонентов FMX3 посвящен работе с компонентом TListBox

Содержание

В VCL компонент TListBox — это список строк, которые можно сортировать, сохранять в файл, загружать из файла и так далее. Думаю, что в специальном представлении этот компонент не нуждается. Что же касается FMX, то здесь уже TListBox — это нечто большее, чем простой список строк. Скорее FMX.TListBox — это список объектов, каждый из которых может быть наделен своими свойствами.

Обзор возможностей компонента TListBox

Каждый  элемент списка может содержать в себе другие объекты, например, компонент TSwitch (переключатель), может иметь другой цвет текста, содержать иконку/картинку и так далее. На рисунке ниже представлен внешний вид мобильного приложения, которое содержит компонент TListBox  с различными настройками элементов списка

FMX.TListBox

Всё, что представлено на рисунке, достигается с помощью свойств компонента и не требует от разработчика ни одной строчки кода. Кроме этого, элементы списка могут также группироваться. Для начала рассмотрим пример того, как можно работать с компонентов TListBox в design-time.

Создайте новой приложение Multi-Device Application и разместите на форме приложения компонент TListBox с вкладки Standard. У вас должно получиться примерно следующее:

TListBox

Теперь, находясь в редакторе формы, выберите стиль отображение формы «Android» и режим просмотра, например, «Android 4» «.

Android Style

В этом режиме Вы можете настроить компонент так, как он должен будет выглядеть на телефоне с Android. Выделите компонент TListBox и в Object Inspector для свойства Align выберите пункт Client, тем самым растянув TListBox по всему доступному месту на форме.

Чтобы добавить в список новый элемент Вы можете воспользоваться контекстным меню компонента:

TListBox context menu Здесь вы можете как сразу добавить новый элемент в список, так и вызвать редактор элементов, выбрав пункт меню «Items Editor…». Выберите пункт «Items Editor…» и в открывшемся редакторе нажмите кнопку «Add Item». В результате, в список добавится новый элемент:

Add new item

Теперь, вернитесь в режим просмотра «Master», выберите на вкладке Standard компонент TSwitch и перетащите его на созданный элемент списка. В итоге, окно Structure в IDE должно выглядеть следующим образом:

TListBox TSwitch

В режиме просмотра «Android» такую манипуляцию с компонентом TSwitch мне проделать не удалось — TSwitch становился дочерним для всего TListBox, а не для конкретного элемента списка.

Теперь ваш элемент списка содержит в себе компонент TSwitch. Снова перейдите в режим просмотра «Android» и настройте положение переключателя, как вам необходимо. например, разместите его по правому краю элемента (Align=Right), сделайте необходимые отступы (Margins) и т.д.

Добавьте в список ещё один элемент, выберите его и перейдите в Object Inspector в свойство ItemData. С помощью этого свойства вы можете назначить элементу списка:

  1. иконку, которая будет отображаться у элемента справа (свойство ItemData.Accessory)
  2. произвольную иконку, которая будет отображаться слева (свойство ItemData.Bitmap)
  3. текст (свойство ItemData.Text)
  4. дополнительную информацию (свойство ItemData.Detail)

Например, используя свойство ItemData, можно создать такой элемент списка:

ItemData.Propeties

Обращу ваше внимание на то, что

внешний вид элемента списка определяется не только значением свойств ItemData, но и установленным значением свойства StyleLookup 

Устанавливая различные свойства у ItemData, вы могли заметить, что в дизайнере элемент списка никак не изменяется. Однако, если выбрать в свойства StyleLookup значение «listboxitembottomdetail», то вы получите внешний вид элемента списка, как на рисунке. Манипулируя свойством StyleLookup, вы можете устанавливать различный вид элемента в списке:

2016-09-02_02-59-32

Ещё одной особенностью FMX.TListBox, отличающей его от аналогичного компонента в VCL является возможность группировки элементов. Каждая группа элементов в списке отделятся элементами TListBoxGroupHeader и TListBoxGroupFooter («шапка» и «подвал» группы). Чтобы продемонстрировать эту возможность, воспользуемся примером, предоставленным Embarcadero.

Перейдите в режим просмотра «Master», удалите все элементы из списка и в обработчике OnCreate главной формы приложения напишите следующий код:

procedure TForm1.FormCreate(Sender: TObject);
var
  c: Char;
  i: Integer;
  Buffer: String;
  ListBoxItem : TListBoxItem;
  ListBoxGroupHeader : TListBoxGroupHeader;
begin
  ListBox1.BeginUpdate;
  for c := 'a' to 'z' do
  begin
    ListBoxGroupHeader := TListBoxGroupHeader.Create(ListBox1);
    ListBoxGroupHeader.Text := UpperCase(c);
    ListBox1.AddObject(ListBoxGroupHeader);
    for i := 1 to 3 do
    begin
      // StringOfChar returns a string with a specified number of repeating characters.
      Buffer := StringOfChar(c, i);
      ListBoxItem := TListBoxItem.Create(ListBox1);
      ListBoxItem.Text := Buffer;
      ListBoxItem.ItemData.Accessory := TListBoxItemData.TAccessory(i);
      ListBox1.AddObject(ListBoxItem);
    end;
  end;
  ListBox1.EndUpdate;
end;

Таким образом, после запуска приложения мы получим группированный список с названиями групп от «a» до «z» где каждая группа будет иметь по три элемента, а каждый элемент группы будет содержать различные иконки в свойства ItemData.Accessory:

Screenshot_2016-09-02-03-21-09

На рисунке выше в компонента ListBox установлено также свойство AlternatingRowBackground в значении True.

Используя тот же самый исходный код приложения, но установив у компонента свойство TListBox.GroupingKind в значение Grouped, можно получить вот такой внешний вид приложения:

Screenshot_2016-09-02-03-28-56

В целом, пожалуй, основные возможности TListBox рассмотрены. С полным описанием свойств и методов компонента можно ознакомиться на странице документации компонента на сайте Embarcadero. Стоит отметить, что:

Embarcadero предупреждает о том, что использование TListBox в мобильных приложениях может приводить к падению производительности.

Посмотрим, как справится компонент с добавлением большого количества элементов в real-time.

Скорость работы FMX.TListBox

В тестовом приложении я добавляю в пустой LisBox 1000 элементов. Приложение запущено на HTC M7. Процедура добавления элементов списка выглядит следующим образом:

uses System.Diagnostics;
 
procedure TForm3.SpeedButton1Click(Sender: TObject);
var
  i: Integer;
  Buffer: String;
  ListBoxItem: TListBoxItem;
  Watch: TStopwatch;
begin
  Watch:=TStopwatch.StartNew;
  ListBox.BeginUpdate;
  for i := 1 to 1000 do
  begin
    // StringOfChar returns a string with a specified number of repeating characters.
    Buffer := 'Element #'+IntToStr(I);
    ListBoxItem := TListBoxItem.Create(ListBox);
    ListBoxItem.Text := Buffer;
    ListBox.AddObject(ListBoxItem);
  end;
  ListBox.EndUpdate;
  Watch.Stop;
  Label1.Text:=Watch.Elapsed.ToString;
end;

Результат работы процедуры показан на рисунке ниже:

Скорость TListBox

Чуть больше 1,5 секунд потребовалось, чтобы заполнить TListBox тысячей элементов. Много это или мало, думаю, понятие относительное, но, тем не менее, embarcadero рекомендует для большей производительности приложений использовать TListView (особенно, если работа ведется с базами данных).

Теперь рассмотрим, какие вопросы возникали у разработчиков при работе с TListBox.

Вопросы и ответы по FMX.TListBox

1. Как отсортировать элементы списка TListBoxItem по различным критериям?

Для сортировки элементов списка используется метод:

procedure TListBox.Sort(Compare: TFmxObjectSortCompare)
 
type
  TFmxObjectSortCompare = reference to function (Left, Right: TFmxObject): Integer;

Допустим, нам необходимо отсортировать элементы по значению свойства Tag элемента. Перепишем процедуру заполнения списке, представленную выше, следующим образом:

procedure TForm3.SpeedButton1Click(Sender: TObject);
var
  i: Integer;
  ListBoxItem: TListBoxItem;
  Watch: TStopwatch;
begin
  Watch:=TStopwatch.StartNew;
  ListBox.BeginUpdate;
  for i := 1 to 1000 do
  begin
    // StringOfChar returns a string with a specified number of repeating characters.
    ListBoxItem := TListBoxItem.Create(ListBox);
    ListBoxItem.Tag:=Random(1000);
    ListBoxItem.Text := 'Element #'+IntToStr(I)+' Tag = '+IntToStr(ListBoxItem.Tag);
    ListBox.AddObject(ListBoxItem);
  end;
  ListBox.EndUpdate;
  Watch.Stop;
  Label1.Text:=Watch.Elapsed.ToString;
end;

Теперь напишем пользовательскую процедуру сортировки:

uses ..., System.Math;
 
function TForm3.SortFunc(Item1, Item2: TFmxObject): Integer;
begin
  Result:=Sign(Item1.Tag-Item2.Tag);
end;

Добавим на форму ещё одну кнопку TSpeedButton клик по которой будет производить сортировку списка:

procedure TForm3.SpeedButton2Click(Sender: TObject);
begin
  ListBox.BeginUpdate;
  ListBox.Sort(SortFunc);
  ListBox.RealignContent;
  ListBox.EndUpdate;
end;

Запускаем приложение, заполняем список:

несортированный TListBox

Нажимаем кнопку сортировки списка:

сортированый список

Как видите, список отсортировался и  был правильно отображен в приложении.

Вопрос и решение проблемы с сортировкой элементов TListBpx впервые опубликованы на сайте fire-monkey.ru.

2. Как определить, что ListBox прокручен в самый конец?

Ответ от разработчика FMX Ярослава Бровина:

Определить, что TListBox (TScrollBox) прокручен до конца можно используя событие OnViewPortPositionChange. Это событие вызывается каждый раз при прокручивании контента. Этот метод возвращает текущее положение ViewPort — позиция окна, в котором отображаются текущие элементы TListBox.

procedure TForm1.ListBox1ViewportPositionChange(Sender: TObject; const OldViewportPosition, NewViewportPosition: TPointF; const ContentSizeChanged: Boolean);
begin
  if NewViewportPosition.Y > ListBox1.ContentBounds.Height - ListBox1.Height then
    ShowMessage('End!');
end;

3. Как поменять цвет выделенного TListBoxItem в ListBox для андроид стиля?

Подробнейший ответ с картинками дан Ярославом Бровиным вот в этом сообщении на сайте fire-monkey.ru.

4. Где взять стандартный стиль в FireMonkey для iOS и Android, используемый по умолчанию?

Ответ: В RAD Studio XE5 и выше входит дизайнер растровых стилей для VCL (BitmapStyleDesigner), который позволяет автоматически создавать стили для FireMonkey. Этот дизайнер находится в папке Bin/bitmapStyleDesigner.exe и содержит внутри себя автоматическую конвертацию любого VCL стиля в FireMonkey. Этот дизайнер также предназначен для внесения правок в стандартные системные стили Android и iOS.

Книжная полка

Автор: Дмитрий Осипов
Название:Delphi. Программирование для Windows, OS X, iOS и Android
Описание Подробно рассматривается библиотека FM, позволяющая создавать полнофункциональное программное обеспечение для операционных систем Windows и OS X, а также для смартфонов и планшетных компьютеров, работающих под управлением Android и iOS
Купить на ЛитРес 359 руб.
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
0 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии