Jump to content
View in the app

A better way to browse. Learn more.

FGX Native

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Добрый вечер,

Мы плотно работаем над новой версией библиотеки FGX Native, в которую войдут новые компоненты-контейнеры и многие другие улучшения. В этой статье мы хотели бы поделиться двумя новыми компонентами-контейнерами TfgVirtualPagerLayout и TfgPagerLayout, которые появятся в релизе 1.13.1.0

TfgVirtualPagerLayout

Это базовый компонент, который предназначен для динамической загрузки/выгрузки страниц по мере их необходимости. В отличии от привычных подходов с добавлением вложенных компонентов заранее в дизайнере, этот компонент запрашивает загрузку/выгрузку страницы через события OnLoadPage и OnUnloadPage по мере их необходимости. Это значит, что фактически вместо загрузки 10-20 страниц, он загружает только видимую и еще 1-2 смежных в зависимости от текущего состояния компонента и, как следствие, ускоряет загрузку приложения.

На базе данного компонента можно легко сделать оптимизированный слайдер изображений. Например вот такой:

Компонент не хранит все страницы у себя и работает по cхожему c TfgCollectionView принципу, те запрашивает необходимую информацию у разработчика через набор событий. Перед использованием компонента, вам необходимо написать обработчики для 3-х событий:

  • OnGetPageCount - вернуть общее количество страниц в компоненте.
  • OnLoadPage - вернуть компонент страницы. Это может быть любой визуальный компонент. Вы можете создавать  страницу в этом событии динамически, а можете реализовать пул объектов, чтобы повторно использовать выгруженные ранее страницы.
  • OnUnloadPage - можно выполнить уничтожение страницы или вернуть страницу в пул объектов для дальнейшего повторного использования.

Типичным примером реализации данных событий может быть такой код, создающий страницы с текстом на базе TfgLabel:

procedure TFormMain.fgVirtualPagerLayout1GetPageCount(Sender: TObject; var ACount: Integer);
begin
  // Сообщаем компоненту о количестве страниц.
  ACount := 100;
end;

procedure TFormMain.fgVirtualPagerLayout1LoadPage(Sender: TObject; const AItemIndex: Integer; var APage: TfgControl);
var
  LPage: TfgLabel;
begin
  // Создаем страницу на базе TfgLabel, которая будет отображать номер страницы.
  LPage := TfgLabel.Create(nil);
  LPage.Font.Size := 30;
  LPage.Text := Format('Page %d', [AItemIndex]);
  APage := LPage;
end;

procedure TFormMain.fgVirtualPagerLayout1UnloadPage(Sender: TObject; const AItemIndex: Integer;
  const APage: TfgControl);
begin
  // Удаляем страницу.
  APage.Free;
end;

В результате получим:

 

Пул страниц

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

  1. Список используемых страниц в компоненте в текущий момент времени - FAcquiredPages.
  2. Список использованных страниц, которые уже не используются в текущий момент времени - FReleasedPages.

Код по объявлению списков выглядит так:

type
  TFormMain = class(TfgForm)
  private
    FAcquiredPages: TList<TfgLabel>;
    FReleasedPages: TObjsetList<TfgLabel>;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

var
  FormMain: TFormMain;

implementation

{$R *.xfm}

uses
  System.SysUtils, FGX.Application, FGX.Dialogs, FGX.Log;

{ TFormMain }

constructor TFormMain.Create(AOwner: TComponent);
begin
  inherited;
  FAcquiredPages := TList<TfgLabel>.Create;
  FReleasedPages := TObjsetList<TfgLabel>.Create;
end;

destructor TFormMain.Destroy;
begin
  FreeAndNil(FAcquiredPages);
  FreeAndNil(FReleasedPages);
  inherited;
end;

Теперь, когда компонент запрашивает страницу мы выполняем простые действия:

  • Если страница есть в пуле, то мы ее извлекаем.
  • Если свободной страницы в пуле нет, то создаем новую.

Когда же страница выгружается компонентом, мы просто возвращаем ее в пул.

procedure TFormMain.fgVirtualPagerLayout1GetPageCount(Sender: TObject; var ACount: Integer);
begin
  ACount := 100;
end;

procedure TFormMain.fgVirtualPagerLayout1LoadPage(Sender: TObject; const AItemIndex: Integer; var APage: TfgControl);
var
  Page: TfgLabel;
begin
  if FReleasedPages.Count = 0 then
  begin
    // В пуле нету свободных страниц, создаем новую
    Page := TfgLabel.Create(nil);
    Page.Font.Size := 30;
  end
  else
    // В пуле есть свободная страница, берем ее
    Page := FReleasedPages.ExtractAt(0);

  // Переносим страницу в список используемых страниц.
  FAcquiredPages.Add(Page);

  // Задаем текст и возвращаем страницу
  Page.Text := Format('Page %d', [AItemIndex]);
  APage := Page;
end;

procedure TFormMain.fgVirtualPagerLayout1UnloadPage(Sender: TObject; const AItemIndex: Integer;
  const APage: TfgControl);
begin
  TfgAssert.IsClass(APage, TfgLabel);

  // Возвращаем страницу в пул для повторного использования
  FAcquiredPages.Remove(APage as TfgLabel);
  FReleasedPages.Add(APage as TfgLabel);
end;

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

Таким образом, этот компонент позволяет ускорить загрузку приложения за счет загрузки только необходимых страниц, а не всех сразу. На базе данного компонента можно легко реализовать слайдер изображение с большим количеством изображений и многое другое.

Динамическое изменение страниц

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

  • Reload - Уведомляет компонент о том, что список страниц изменился и надо заново его построить.
  • NotifyPageInserted - Уведомляет компонент, что в список вставлены новые страницы по указанным индексам.
  • NotifyPageRemoved - Уведомляет компонент, что из списка нужно удалить страницы по указанным индексам.

Состав страниц нельзя менять в процессе переключения вкладок!

Дополнительные события

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

  • OnChanged - Вызывается только при интерактивной смене вкладки, как только компонент понимает на какую вкладку окончательно переключается пользователь. 
  • OnBeginDragging - Вызывается, когда пользователь опустил палец на экран и начал двигать содержимое. 
  • OnEndDragging - Вызывается, когда пользователь поднял палец с экрана и закончил двигать содержимое.
  • OnBeginScrolingAnimation - Вызывается, когда началась анимация смены вкладки.
  • OnEndScrolingAnimation - Вызывается, когда анимация смены вкладки закончилась.

TfgPagerLayout 

Этот компонент-контейнер построен на базе TfgVirtualPagerLayout и в отличии от TfgVirtualPagerLayout выравнивает все добавленные в него компоненты по страницам. Он не выгружает/загружает страницы и по сути является аналогом TfgPageControl. Вы добавляете в него любые компоненты и TfgPagerLayout сам осуществляет их выравнивание и переключение.
 

0 Comments

Recommended Comments

There are no comments to display.

Recently Browsing 0

  • No registered users viewing this page.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.