Delphi FMX 初始化列表视图

Delphi FMX initialize listview

我有一个 FMX 应用程序,它在选项卡控件的不同页面上有列表视图。切换选项卡时,我会动态填充和格式化列表条目,例如通过更改垂直位置。第一次显示列表视图时,项目显示在错误的位置。 Windows 或 Android 与 Delphi 西雅图和悉尼版本相同。

我的问题是:添加项目后我可以(或必须)做些什么来初始化列表视图?

要重现我的问题,您可以创建一个新的 'FMX Header/Footer with navigation' 应用程序。在第二个选项卡上添加一个客户端对齐的列表视图,并在 tabcontrol onchange 处理程序中添加以下代码:

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;

当运行应用程序并在header中按下Next-Button时,第一次绘制列表,显示的列表视图文本都以相同的方式对齐。来回切换tabcontrol的两个页面时,第二次正确绘制列表(意味着用placeoffset格式化)。

相关文件的完整列表为:

主程序(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.

主表单位(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.

主窗体(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

如果您未在项目中使用样式,请插入对以下内容的调用:

ListView1.ApplyStyleLookup;

在表格 OnCreate 事件中,

(以后用到样式就不用了,不过也没什么坏处)

第一次点击后Next:所有偶数按代码偏移