delphifiremonkeytlistview

Text Alignment of ListViewItem


In Firemonkey of Delphi 10.4. I want to build a list view where the listview item text appears either left- or right-aligned depending on the list item content.

enter image description here

I do this as follows:

procedure TForm1.FormCreate(Sender: TObject);

  procedure AddItem(No: integer);
  var
    Item: TListViewItem;
  begin
    Item := ListView1.Items.AddItem(No);
    Item.Text := 'Text item No ' + No.ToString;
    Item.Tag := No;
    if No mod 2 = 0 then
      Item.Objects.TextObject.TextAlign := TTextAlign.Leading
    else
      Item.Objects.TextObject.TextAlign := TTextAlign.Trailing;
  end;

var
  c: integer;
begin
  for c := 0 to 9 do
    AddItem(c);
end;

However, this does not work on all platforms. But as soon as the ListView changes its size, all ListItems appear flush on the left. Is there a better way to do this?

As a workaround, I have done the following:

procedure TForm1.ListView1Resized(Sender: TObject);
var
  c: integer;
begin
  for c := 0 to ListView1.ItemCount - 1  do
    if ListView1.Items[c].Tag mod 2 = 0 then
      ListView1.Items[c].Objects.TextObject.TextAlign := TTextAlign.Leading
    else
      ListView1.Items[c].Objects.TextObject.TextAlign := TTextAlign.Trailing;
end;

Solution

  • With ItemAppearance=ListItem this problem cannot be solved, because in the internal ResetView method the Item.Objects.TextObject all properties will written back to ItemAppearanceObjects.ItemObjects.

    Therefore, ItemAppearance must be set to DynamicAppearance for this application. Two TextObjectAppearance objects must be manually created in the Structure View under ListView.ItemAppearance.Item, where Text1 must be set to a TextAlign=Leading and Text2 to TextAlign=Trailing.

    enter image description here

    After that, only one Text Object has to be filled with the text:

    procedure TForm1.FormCreate(Sender: TObject);
    
      procedure AddItem(No: integer);
      var
        Item: TListViewItem;
      begin
        Item := ListView1.Items.AddItem(No);
        if No mod 2 = 0 then
          Item.Data['Text1'] := 'Text item No ' + No.ToString
        else
          Item.Data['Text2'] := 'Text item No ' + No.ToString
      end;
    
    var
      c: integer;
    begin
      for c := 0 to 9 do
        AddItem(c);
    end;
    

    Here is the corresponding FMX file:

    object Form1: TForm1
      Left = 0
      Top = 0
      Caption = 'Form1'
      ClientHeight = 480
      ClientWidth = 640
      FormFactor.Width = 320
      FormFactor.Height = 480
      FormFactor.Devices = [Desktop]
      OnCreate = FormCreate
      DesignerMasterStyle = 0
      object ListView1: TListView
        ItemAppearanceClassName = 'TDynamicAppearance'
        ItemEditAppearanceClassName = 'TDynamicAppearance'
        HeaderAppearanceClassName = 'TListHeaderObjects'
        FooterAppearanceClassName = 'TListHeaderObjects'
        Align = Client
        Size.Width = 640.000000000000000000
        Size.Height = 480.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 0
        ItemAppearanceObjects.ItemObjects.ObjectsCollection = <
          item
            AppearanceObjectName = 'Text1'
            AppearanceClassName = 'TTextObjectAppearance'
            Appearance.TextAlign = Leading
          end
          item
            AppearanceObjectName = 'Text2'
            AppearanceClassName = 'TTextObjectAppearance'
            Appearance.TextAlign = Trailing
          end>
        ItemAppearanceObjects.ItemEditObjects.ObjectsCollection = <
          item
            AppearanceObjectName = 'Text1'
            AppearanceClassName = 'TTextObjectAppearance'
          end>
      end
    end