I have a FMX App that has listviews on different pages of a tabcontrol. When switching tabs I dynamically fill and format the list entries e.g. by changing the vertical placement. When a listview is shown at the first time the items are shown at the wrong position. Happens the same on Windows or Android with Delphi versions Seattle and Sydney.
My question is: Is there anything that I can (or have to) do to initialize the listview after adding the items?
To reproduce my problem, you can create a new 'FMX Header/Footer with navigation' application. On the second tab add a client aligned listview an add the following code in the tabcontrol onchange handler:
procedure THeaderFooterwithNavigation.TabControl1Change(Sender: TObject);
var
i: integer;
it: TListViewItem;
begin
if TabControl1.ActiveTab = TabItem2 then
begin
ListView1.Items.Clear;
for i := 1 to 10 do
begin
it := ListView1.Items.Add;
it.Text := inttostr(i);
if odd(i) then
it.Objects.TextObject.PlaceOffset.Y := 0
else
it.Objects.TextObject.PlaceOffset.Y := 10;
end;
end;
end;
When running the App and pressing the Next-Button in the header, the list is drawn for the first time with the listviews text shown all aligned in the same way. When switching back and forth the two pages of the tabcontrol, the list is drawn correctly (means like formatted with placeoffset) the second time.
The full listings of the relevant files are:
Main program (dpr):
program HeaderFooterNavigation;
uses
System.StartUpCopy,
FMX.Forms,
HeaderFooterFormwithNavigation in 'HeaderFooterFormwithNavigation.pas' {HeaderFooterwithNavigation};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(THeaderFooterwithNavigation, HeaderFooterwithNavigation);
Application.Run;
end.
Main form unit (pas):
unit HeaderFooterFormwithNavigation;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes,
System.Variants,
FMX.Types, FMX.Controls, FMX.Graphics, FMX.Forms, FMX.Dialogs, FMX.TabControl,
System.Actions, FMX.ActnList,
FMX.Objects, FMX.StdCtrls, FMX.Controls.Presentation, FMX.ListView.Types,
FMX.ListView.Appearances, FMX.ListView.Adapters.Base, FMX.ListView;
type
THeaderFooterwithNavigation = class(TForm)
ActionList1: TActionList;
PreviousTabAction1: TPreviousTabAction;
TitleAction: TControlAction;
NextTabAction1: TNextTabAction;
TopToolBar: TToolBar;
btnBack: TSpeedButton;
ToolBarLabel: TLabel;
btnNext: TSpeedButton;
TabControl1: TTabControl;
TabItem1: TTabItem;
TabItem2: TTabItem;
BottomToolBar: TToolBar;
ListView1: TListView;
procedure FormCreate(Sender: TObject);
procedure TitleActionUpdate(Sender: TObject);
procedure FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
Shift: TShiftState);
procedure btnNextClick(Sender: TObject);
procedure TabControl1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
HeaderFooterwithNavigation: THeaderFooterwithNavigation;
implementation
{$R *.fmx}
{$R *.LgXhdpiPh.fmx ANDROID}
{$R *.iPhone4in.fmx IOS}
procedure THeaderFooterwithNavigation.TabControl1Change(Sender: TObject);
var
i: integer;
it: TListViewItem;
begin
if TabControl1.ActiveTab = TabItem2 then
begin
ListView1.Items.Clear;
for i := 1 to 10 do
begin
it := ListView1.Items.Add;
it.Text := inttostr(i);
if odd(i) then
it.Objects.TextObject.PlaceOffset.Y := 0
else
it.Objects.TextObject.PlaceOffset.Y := 10;
end;
end;
end;
procedure THeaderFooterwithNavigation.TitleActionUpdate(Sender: TObject);
begin
if Sender is TCustomAction then
begin
if TabControl1.ActiveTab <> nil then
TCustomAction(Sender).Text := TabControl1.ActiveTab.Text
else
TCustomAction(Sender).Text := '';
end;
end;
procedure THeaderFooterwithNavigation.btnNextClick(Sender: TObject);
begin
TabControl1.ActiveTab := TabItem2;
end;
procedure THeaderFooterwithNavigation.FormCreate(Sender: TObject);
begin
{ This defines the default active tab at runtime }
TabControl1.First(TTabTransition.None);
end;
procedure THeaderFooterwithNavigation.FormKeyUp(Sender: TObject; var Key: Word;
var KeyChar: Char; Shift: TShiftState);
begin
if (Key = vkHardwareBack) and (TabControl1.TabIndex <> 0) then
begin
TabControl1.First;
Key := 0;
end;
end;
end.
Main form (fmx):
object HeaderFooterwithNavigation: THeaderFooterwithNavigation
Left = 0
Top = 0
Caption = 'HeaderFooter'
ClientHeight = 567
ClientWidth = 384
FormFactor.Width = 1440
FormFactor.Height = 900
FormFactor.Devices = [Desktop]
OnCreate = FormCreate
DesignerMasterStyle = 0
object TopToolBar: TToolBar
Anchors = []
Size.Width = 384.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
object ToolBarLabel: TLabel
Action = TitleAction
Align = Contents
Enabled = True
Size.Width = 384.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
StyleLookup = 'toollabel'
TextSettings.HorzAlign = Center
end
object btnBack: TSpeedButton
Action = PreviousTabAction1
Align = MostLeft
Enabled = True
ImageIndex = -1
Size.Width = 65.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
StyleLookup = 'backtoolbutton'
end
object btnNext: TSpeedButton
Action = NextTabAction1
Align = MostRight
Enabled = True
ImageIndex = -1
Position.X = 340.000000000000000000
Size.Width = 44.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
StyleLookup = 'nexttoolbutton'
OnClick = btnNextClick
end
end
object TabControl1: TTabControl
Align = Client
FullSize = True
Size.Width = 384.000000000000000000
Size.Height = 479.000000000000000000
Size.PlatformDefault = False
TabHeight = 49.000000000000000000
TabIndex = 0
TabOrder = 1
TabPosition = Top
OnChange = TabControl1Change
Sizes = (
384s
430s
384s
430s)
object TabItem1: TTabItem
CustomIcon = <
item
end>
IsSelected = True
Size.Width = 191.000000000000000000
Size.Height = 49.000000000000000000
Size.PlatformDefault = False
StyleLookup = ''
TabOrder = 0
Text = 'Caption Tab Item #1'
ExplicitSize.cx = 8.000000000000000000
ExplicitSize.cy = 8.000000000000000000
end
object TabItem2: TTabItem
CustomIcon = <
item
end>
IsSelected = False
Size.Width = 191.000000000000000000
Size.Height = 49.000000000000000000
Size.PlatformDefault = False
StyleLookup = ''
TabOrder = 0
Text = 'Caption Tab Item #2'
ExplicitSize.cx = 8.000000000000000000
ExplicitSize.cy = 8.000000000000000000
object ListView1: TListView
ItemAppearanceClassName = 'TListItemAppearance'
ItemEditAppearanceClassName = 'TListItemShowCheckAppearance'
HeaderAppearanceClassName = 'TListHeaderObjects'
FooterAppearanceClassName = 'TListHeaderObjects'
Align = Client
Size.Width = 384.000000000000000000
Size.Height = 430.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
end
end
end
object BottomToolBar: TToolBar
Align = Bottom
Anchors = [akLeft]
Position.Y = 523.000000000000000000
Size.Width = 384.000000000000000000
Size.Height = 44.000000000000000000
Size.PlatformDefault = False
StyleLookup = 'bottomtoolbar'
TabOrder = 2
end
object ActionList1: TActionList
Left = 176
Top = 56
object TitleAction: TControlAction
Category = 'Tab'
Text = 'TitleAction'
OnUpdate = TitleActionUpdate
end
object PreviousTabAction1: TPreviousTabAction
Category = 'Tab'
TabControl = TabControl1
ShortCut = 137
end
object NextTabAction1: TNextTabAction
Category = 'Tab'
TabControl = TabControl1
end
end
end
