Reputation: 1222
I'm using this code to add an item to a listbox, but I can't figure out how to dynamically resize the height of the item to fit the text:
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;
I tried using the code from this example (modified for TListBoxItem), but it didn't work.
Edit: The height of the ListBoxItem can be set by just adding Item.Height := 100;
at the end of the code above, but I need to know the height of text to decide what size the ListBoxItem needs to be, so to clarify my question, how do I get the height of the text in the list box item?
Upvotes: 1
Views: 12900
Reputation: 109
Here is the Mike Sutton's code, improved and tested by me. Works for case of an Item with a Detail text (.ItemData.Detail). The variant with TextLayout did not work for me.
This code is tested for Windows and Android application.
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;
Upvotes: 0
Reputation: 99
As mentioned by Mike Sutton, it can be done OnApplyStyleLookup
event.
I do it using a 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;
Note that MaxSize
is limitating. For example, aPoint.Y
will limit the final TextHeight
. You should set it large because, whatever TextHeight
should be, if myLayout.TextHeight
is larger than myLayout.MaxSize.Y
then myLayout.TextHeight
will be set to myLayout.MaxSize.Y
.
Here's a list of TTextLayout
properties.
Upvotes: 1
Reputation: 964
There are one important thing about changing size of control: "For mobile platform, firemonkey fix height and with some controls". Because:
However, you can remove this contraints. Look at the my solution this (Auto translated with Google): Can not increase the height TProgressBar
This article about TProgressBar, But you can use this approach also for a TListBoxItem.
Upvotes: -1
Reputation: 4211
Pop your resizing code in the OnApplyStyleLookup event.
Written off the top of my head and way past bedtime:
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;
You will, of course, need to set the event for every item you create.
Upvotes: 1