清除firemonkey应用程序

时间:2015-04-28 16:45:12

标签: android delphi mobile firemonkey

我有一个针对Android手机的firemonkey应用程序,在XE7,Win8中。我在下面的程序ShowMsg中将消息显示到VertScrollBox中。

我想清除VertScrollBox,我正在尝试使用ClearVertScrollBox程序来完成它,但我没有成功。

我在这里做错了什么?

procedure TForm1.ClearVertScrollBox;
var i:integer;
begin
  for i:=VSB.ControlsCount-1 downto 0 do
  begin
    if (VSB.Controls[i] is TCalloutRectangle) then begin
      VSB.Controls[i].DisposeOf;
      VSB.Controls[i]:=nil;
    end;
  end;
  VSB.Repaint;
end;

var VSB: TVertScrollBox;

procedure TForm1.ShowMsg(Title,GCMMsg,Msg:string);
var
  CR: TCalloutRectangle;
  L: TText;
begin
  CR := TCalloutRectangle.Create(Self);
  CR.Parent := VSB;
  CR.Align := TAlignLayout.alTop;
  CR.CalloutPosition := TCalloutPosition.cpLeft;
  CR.Margins.Top := 10;
  CR.Margins.Bottom := 10;
  CR.Margins.Right := 5;
  CR.Height := 75;

  L := TText.Create(Self);
  L.Parent := CR;
  L.Align := TAlignLayout.alTop;
  L.Text := Title;
  L.Margins.Left := 15;
  L.Margins.Right := 5;
  L.Width := CR.Width-20;
  L.Height:=20;

  L := TText.Create(Self);
  L.Parent := CR;
  L.Align := TAlignLayout.alClient;
  L.Text := GCMMsg;//GCMMsg+':'+Msg;
  L.Margins.Left := 15;
  L.Margins.Right := 5;
  L.Width := CR.Width-20;

  L.WordWrap := True;
  L.AutoSize := True;
end;

2 个答案:

答案 0 :(得分:0)

您的ClearVertScrollBox只是需要进行一些调整,您只是通过其控制并检查其中一个是TCalloutRectangle,但TVertScrollBox不只是存储您的TCalloutRectangle在第一个控制节点树中。

TVertScrollBox有一个TScrollContent,可以作为存储控件的控件

所以这样就足够了

var
    I,II : Integer; 
begin
for i:= VSB.ControlsCount-1 downto 0 do
    begin
        if VSB.Controls[I].ClassType = TScrollContent then
        begin
            for II := VSB.Controls[I].ControlsCount-1 downto 0 do
            begin
                if VSB.Controls[I].Controls[II].ClassType = TCalloutRectangle then
                begin
                    VSB.Controls[I].Controls[II].Parent := nil;
                end;
            end;
        end;
    end; 
end;

您在创建TCalloutRectangle

时也会造成内存泄漏

您正在与所有者创建所有对象,更具体地说,您使用Self关键字将表单设置为所有者,因此即使您“直观地”将其从TVertScrollBox中移除对象仍由您的表单拥有,对象引用计数永远不会达到0意味着ARC将无法释放它。

而不是像这样的所有者创建对象:

CR := TCalloutRectangle.Create(Self);

这样做

CR := TCalloutRectangle.Create(nil);

如果您已将其分配给父级,则无需将其分配给所有者,请为TCalloutRectangleTText(我假设是TLabel?)对象执行此操作

如果您只与父母一起创建对象并使用新代码从TVertScrollBox中删除它们,您将破坏对这些对象的所有引用并释放它们,这意味着不需要DisposeOf致电

答案 1 :(得分:0)

我使用下面的代码清除滚动框,就我而言,我只想删除列表中的所有项目,而不是特定的项目。

unit uScrollBoxHelper;

interface

uses FMX.Layouts;

type
  TVertScrollBoxHelper = class helper for TVertScrollBox
  public
    procedure Clear;
  end;

  THorzScrollBoxHelper = class helper for THorzScrollBox
  public
    procedure Clear;
  end;

implementation

{ TVertScrollBoxHelper }

procedure TVertScrollBoxHelper.Clear;
var
  I: Integer;
begin
  for I := self.Content.ChildrenCount - 1 downto 0 do
    self.Content.Children.Items[I].DisposeOf;
end;

{ THorzScrollBoxHelper }

procedure THorzScrollBoxHelper.Clear;
var
  I: Integer;
begin
  for I := self.Content.ChildrenCount - 1 downto 0 do
    self.Content.Children.Items[I].DisposeOf;
end;

end.

然后,当我想在表单中使用代码时,我便会这样做:

  VertScrollBox1.BeginUpdate;
  VertScrollBox1.Clear;
...
  VertScrollBox1.EndUpdate;