Как настроить высоту элементов ListBox, чтобы они соответствовали тексту в Firemonkey (android)?

1

Я использую этот код для добавления элемента в список, но я не могу понять, как динамически изменять размер элемента в соответствии с текстом:

procedure TmForm.AddItemBtnClick(Sender: TObject);
var
  Item: TListBoxItem;
begin
  Item := TListBoxItem.Create(nil);
  Item.Parent := SomeListBox;
  Item.StyleLookup := 'listboxitemstyle';
  Item.Text :=
              'Pe cararea lunga scurta se ducea un om venind, si-n tacerea lui ' +
              'profunda se auzea borborosind. Cantr-o noapte intunecoasa soarel' +
              'e lucea pe cer, iara eu cu barca in casa ma plimbam ca un boier.';
  Item.WordWrap := true;
  Item.StyledSettings := [TStyledSetting.ssFamily] + [TStyledSetting.ssStyle] + [TStyledSetting.ssFontColor];
  Item.Font.Size := 14;
end;

Я попытался использовать код из этого примера (измененный для TListBoxItem), но он не сработал.

Изменить: высоту ListBoxItem можно установить, просто добавив Item.Height := 100; в конце кода выше, но мне нужно знать высоту текста, чтобы решить, какой размер должен быть ListBoxItem, поэтому, чтобы уточнить мой вопрос, как мне получить высоту текста в элементе списка?

Теги:
delphi-xe5
firemonkey

4 ответа

1

Как уже упоминалось Майком Саттоном, это может быть сделано событие OnApplyStyleLookup. Я использую TTextLayout:

uses 
... ,FMX.TextLayout;

procedure TfrmForm1.ListBoxItem1ApplyStyleLookup(Sender: TObject);
var
  myLayout: TTextLayout;
  aPoint: TPointF;
begin

  myLayout := TTextLayoutManager.DefaultTextLayout.Create;
  myLayout.BeginUpdate;

  // Setting the layout MaxSize
  aPoint.X := ListBoxItem1.Width;
  aPoint.Y := TfrmForm1.Height;
  myLayout.MaxSize := aPoint;

  myLayout.Text := ListBoxItem1.Text;
  myLayout.WordWrap := True ;
  myLayout.Font := ListBoxItem1.Font;
  myLayout.HorizontalAlign := ListBoxItem1.TextSettings.HorzAlign;
  myLayout.VerticalAlign := ListBoxItem1.TextSettings.VertAlign;
  myLayout.Padding := ListBoxItem1.Padding;
  // set other properties as needed        

  myLayout.EndUpdate;

  ListBoxItem1.Height := Trunc(myLayout.TextHeight) + 3 ; // +3px to be sure to see entire text

end;

Обратите внимание, что MaxSize ограничивает. Например, aPoint.Y ограничит окончательный TextHeight. Вы должны установить его большим, потому что, независимо от TextHeight, если myLayout.TextHeight больше, чем myLayout.MaxSize.Y то myLayout.TextHeight будет установлен в myLayout.MaxSize.Y.

Вот список свойств TTextLayout.

1

Введите свой код изменения размера в событие OnApplyStyleLookup.

Списано с головы и ног перед сном:

procedure TForm1.ListBoxItemApplyStyleLookup(Sender: TObject);
var O: TFMXObject;
begin
  O := (Sender as TListBoxItem).FindStyleResource('text');
  if O is TText then
    (Sender as TListBoxItem).Height := (O as TText).Height;
end;

Разумеется, вам нужно будет установить событие для каждого создаваемого вами элемента.

  • 0
    Я добавил в свой код Item.OnApplyStyleLookup: = ListBoxItemApplyStyleLookup; и код, который вы опубликовали, но результаты те же, на самом деле код в ListBoxItemApplyStyleLookup никогда не достигается.
  • 0
    Мы не можем вручную установить Высота для ListItem таким образом, потому что для мобильных платформ firemonkey в стиле фиксирует высоту элемента, поэтому вы не можете напрямую изменять высоту.
Показать ещё 6 комментариев
0

Вот код Майка Саттона, улучшенный и проверенный мной. Работает для случая элемента с детальным текстом (.ItemData.Detail). Вариант с TextLayout не работал для меня.

Этот код протестирован для приложений Windows и Android.

procedure TTestForm.ListBoxItem1ApplyStyleLookup(Sender: TObject);
var item: TListBoxItem absolute Sender;

  function CalcHeight( SubStyle: String ): Single;
  var Obj: TFMXObject; T: TText absolute Obj;
  begin
    Obj := item.FindStyleResource(SubStyle);
    if Obj is TText
    then Result := T.Canvas.TextHeight(T.Text)
                 + T.Margins.Top + T.Margins.Bottom
                 + T.Padding.Top + T.Padding.Bottom
    else Result := 0;
  end;

begin
  item.Height := CalcHeight('text')
               + CalcHeight('detail');
end;
-1

Есть одна важная вещь в изменении размера элемента управления: "Для мобильной платформы, высота фиксации firemonkey и некоторые элементы управления". Потому как:

  1. Руководство по стилю UI для каждой платформы определяет правила размера стандартных элементов управления.
  2. Firemonkey использует растровый стиль, поэтому вы не можете изменить какой-то размер управления, потому что вы потеряете качество просмотра

Однако вы можете удалить эти ограничения. Посмотрите на мое решение (Auto переведен с Google): невозможно увеличить высоту TProgressBar

Эта статья о TProgressBar, но вы также можете использовать этот подход для TListBoxItem.

  • 1
    Для ListBoxItem нет поля FixedHeight, а высоту элемента можно установить, просто добавив Item.Height: = 95; в коде, но мне нужно знать высоту текста, чтобы узнать, какое значение установить высоту ListBoxItem.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню