Delphi/FMX: 如何在之前添加的所有顶部对齐组件下添加一个动态创建的顶部对齐组件,而不是倒数第二个?

Delphi/FMX: How to add a dynamically created top-aligned component under all previously added top-aligned components, instead of second from the top?

我正在用 Delphi 和 FMX 为 Android 开发一个应用程序。在按钮的点击过程中,我动态创建了一个 TPanel(其中包含一些组件),然后将其添加到 TVertScrollBox。我希望 TPanel 堆叠在一起,所以我将 Align 属性 设置为 Top.

procedure TMainForm.AddGroupButtonClick(Sender: TObject);
var Group : TPanel;
begin
   Group := TPanel.Create(Self);
   Group.Parent := Groups;         // where Groups is a TVertScrollBox on the form
   Group.Align := TAlignLayout.Top;

   //Then I create some other components and set their Parent to Group
end;

用户可能希望在所有其他 TPanel 下添加新的 TPanel。但是,除非之前没有添加 TPanel,否则每个新的 TPanel 都会直接添加到最上面的 TPanel 下,即从顶部数第二个。

为什么会这样?如何在之前添加的所有 TPanel 下添加新的 TPanel?

我在这里看到了一个类似的问题,但他们使用的是 VCL,其中显然有一个 Top-属性 您可以更改。但是在使用 FMX 组件时似乎没有。

当您创建新的 Firemonkey 面板时,其 Position 属性 默认为 X=0, Y=0

当您设置 Align := TAlignLayout.Top; 时,它会与之前放置的组件进行比较,发现 Y = 0 处已经有一个面板,并将新面板挤压到现有面板下方。

将新面板置于所有其他面板集下方

...
Group.Position.Y := 1000; // any sufficiently large value (bigger than the last panel's Y)
Group.Align := TAlignLayout.Top;

这是因为当您动态创建一个 TPanel 时,它有一个 (0,0) 位置,所以它比之前创建的所有其他面板都高。您可以使用作弊方法将新创建的面板创建在其他面板下方。这里有两个简单但有点肮脏的解决方案。

方法一:

   Group := TPanel.Create(Self);
   Group.Parent := Groups;         // where Groups is a TVertScrollBox on the form
   Group.Align := TAlignLayout.bottom; // :D it firstly created it at bottom and then move it to top
   Group.Align := TAlignLayout.Top;

方法二:

   Group := TPanel.Create(Self);
   Group.Parent := Groups;         // where Groups is a TVertScrollBox on the form
   Group.Position.Y:=Groups.Height+1;
   Group.Align := TAlignLayout.Top;

希望能解决你的问题