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.
  • Status: Fixed
  • Priority: Major
  • Resolution: Works as expected
  • Platform: Android
  • Affects version 1.13.3.0

Добрый день

Обнаружена ошибка прорисовывания контролов при реализации следующей идеи:

На основной форме есть TfgVerticalScrollBar, внутри которого в рантайме я создаю карточки на базе TfgCardPanel. Каждая карточка содержит свой  список на базе TfgCollectionView. Карточки очень часто обновляются, и изначально их количество не известно. Поэтому при каждом обновлении, я создаю новые карточки путем клонирования базовой карточки приблизительно вот так:

Спойлер
procedure TFormMain.BtnFillTap(Sender: TObject);
var
  Panel: TfgCardPanel;
  Header, Fields: TfgLayout;
  Hlabel: TfgLabel;
  View: TfgCollectionView;
  var I,K,L: Integer;
begin
  SbWithPanel.BeginUpdate;
  SbWithPanel.DeleteControls;
  CpBase.Visible := True;
  try
    L := Random(2)+1;
    for I := 1 to L do
    begin
      Panel := cpBase.Clone(True) as TfgCardPanel;
      Panel.Tag := I;

      Header := Panel.FindComponent('LtPanelName') as TfgLayout;

      Hlabel := Panel.FindComponent('LbPanelName') as TfgLabel;
      Hlabel.Text := Format('ПАНЕЛЬ № %d',[I]);

      K := Random(10)+1;
      View := Panel.FindComponent('CvBase') as TfgCollectionView;
      View.Tag := K;


      Fields := Panel.FindComponent('LtFields') as TfgLayout;

      Panel.Size.Height := Trunc(Header.Size.Height) + (K * Trunc(Fields.Size.Height));

      SbWithPanel.AddControl(Panel);

      View.ReloadItems;
    end;

    SbWithPanel.Realign;
  finally
    CpBase.Visible := False;
    SbWithPanel.EndUpdate;
  end;
end;

 

Учитывая, что базовую карточку не должно быть видно, я ее скрываю в момент создания формы:

Спойлер
procedure TFormMain.fgFormCreate(Sender: TObject);
begin
  CpBase.Visible := False;
end;

 

И вот тут происходит магия.  Если карточка всего одна, то её ширина не растягивается на всю ширину экрана, и только при смене ориентации экрана карточка воспроизводится полностью. Если же создавать одновременно две и более карточки, то они отображаются правильно.

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

 

CloneCardPanel.zip

User Feedback

Recommended Comments

  • Administrators

Если речь идет о скролл боксе в режиме автоматическом расчете размера контента, то он сам практически не пересчитывает размер. Это сделано из-за того, что случаев, когда размер надо вычислить, очень много. А это в свою очередь может привести к деградации производительности. Поэтому, если вы добавляете новый компонент в скроллбокс (тот же метод клон) или меняете его свойства выравнивания, то вам после всех манипуляций нужно вызвать у скроллбокса метод RecalculateContentSize, это приведет к вычислению размера контента и выравниванию всех вложенных компонентов. Так что это такая особенность работы компонента, которая связана с оптимизацией.

Benten

Active subscription
13 часов назад, Yaroslav Brovin сказал:

Если речь идет о скролл боксе в режиме автоматическом расчете размера контента, то он сам практически не пересчитывает размер. Это сделано из-за того, что случаев, когда размер надо вычислить, очень много. А это в свою очередь может привести к деградации производительности. Поэтому, если вы добавляете новый компонент в скроллбокс (тот же метод клон) или меняете его свойства выравнивания, то вам после всех манипуляций нужно вызвать у скроллбокса метод RecalculateContentSize, это приведет к вычислению размера контента и выравниванию всех вложенных компонентов. Так что это такая особенность работы компонента, которая связана с оптимизацией.

Спасибо, Ярослав, помогло. Я догадывался, что все дело в каком-то "хитром" методе, но грешил на то, что размер карточки сжимается, когда делаешь ее не видимой.

Зря писал в багтрекер, надо было оформить тему на форуме. Вообщем, спасибо еще раз.

  • Administrators

На здоровье.

Дело в том, что FlexBox дает очень много параметров и условий, которые влияют на размер родителя. Например, во FlexBox изменение параметров дочерних компонентов могут влиять на размер их родителей и наоборот. Поэтому задача отслеживания становится хоть и реальной, но очень затратной по ресурсам, так как требуется вводить большое число нотификаций от дочерних компонентов в дереве до корня. Поэтому Мы решили отказаться от такой активной модели. И текущий подход работает гарантированно один раз и быстро.

6 часов назад, Benten сказал:

Зря писал в багтрекер, надо было оформить тему на форуме. Вообщем, спасибо еще раз.

Не так важно, куда завели. Главное задали вопрос и подробно объяснили проблему 🙂 Надо нам будет постараться добавить демо пример по динамическому добавлению компонентов в скролл бокс.

  • Administrators

Изменено Статус на Fixed

Изменено Резолюция на Works as expected

Create an account or sign in to comment

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.