TAniIndicator不旋转 - 加载tlistview

时间:2017-08-06 17:48:22

标签: android firemonkey delphi-10.2-tokyo

我是TAniindicator组件的新手,所以出于测试目的,我已经组建了一个项目,它将构建一个listview并在构建listview时显示/旋转Aniindicator。

type
TLoadThread = class(TThread)
public
 constructor Create; reintroduce;
protected
 procedure Process;
 procedure Execute; override;
end;    

constructor TLoadThread.Create;
begin
 inherited Create(True);
 FreeOnTerminate := True;
end;

procedure TLoadThread.Process;
begin
 Form1.BuildListView;
end;

procedure TLoadThread.Execute;
begin
 inherited;
 FreeOnTerminate := True;
 Synchronize(Process);
end;

var _loadThread : TLoadThread;

procedure TForm1.ThreadTerminated(Sender: TObject);
begin  
 AniIndicator1.Enabled := False;
 AniIndicator1.Visible := False;
end;

procedure TForm1.BuildListView;
var i : integer;
    LI : TListViewItem;
 begin
  Listview1.BeginUpdate;
 try
  for i := 1 to 2000 do
  begin
   LI := Listview1.Items.Add;
   LI.Text := 'Listview Item ' + IntToStr(i);
  end;
 finally
  Listview1.EndUpdate;
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 AniIndicator1.Visible := False;
 _loadThread := nil;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 _loadThread := TLoadThread.Create;
 _loadThread.OnTerminate := ThreadTerminated;
 _loadThread.Start;
 AniIndicator1.Enabled := True;
end;

我以为自己走在了正确的轨道上,但这似乎没有用,有人能解释我做错了吗?

1 个答案:

答案 0 :(得分:0)

您的工作线程将所有时间都花在Process()方法中,TThread.Synchronize()方法正在Process()调用,因此它在主UI线程中运行。 TAniIndicator未处理UI消息,这就是TLoadThread无效的原因。

按原样,你的工作线程完全没用。您的所有代码都在主UI线程中运行。所以,你也可以完全摆脱procedure TForm1.FormCreate(Sender: TObject); begin AniIndicator1.Visible := False; end; procedure TForm1.BuildListView; var i : integer; LI : TListViewItem; begin AniIndicator1.Visible := True; AniIndicator1.Enabled := True; ListView1.BeginUpdate; try for i := 1 to 2000 do begin LI := ListView1.Items.Add; LI.Text := 'ListView Item ' + IntToStr(i); if (i mod 100) = 0 then Application.ProcessMessages; end; finally ListView1.EndUpdate; AniIndicator1.Enabled := False; AniIndicator1.Visible := False; end; end; procedure TForm1.Button1Click(Sender: TObject); begin BuildListView; end;

type
  TLoadThread = class(TThread)
  public
    constructor Create; reintroduce;
  protected
    procedure Execute; override;
  end;

constructor TLoadThread.Create;
begin
  inherited Create(True);
  FreeOnTerminate := True;
end;

procedure TLoadThread.Execute;
begin
  Form1.BuildListView;
end;

var
  _loadThread : TLoadThread = nil;

procedure TForm1.ThreadTerminated(Sender: TObject);
begin
  _loadThread := nil;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  AniIndicator1.Visible := False;
end;

procedure TForm1.BuildListView;
var
  i : integer;
begin
  TThread.Synchronize(nil,
   procedure
   begin
     AniIndicator1.Visible := True;
     AniIndicator1.Enabled := True;
     ListView1.BeginUpdate;
   end
  );
  try
    for i := 1 to 2000 do
    begin
      TThread.Synchronize(nil,
        procedure
        var
          LI : TListViewItem;
        begin
          LI := ListView1.Items.Add;
          LI.Text := 'ListView Item ' + IntToStr(i);
        end
      );
    end;
  finally
    TThread.Synchronize(nil,
      procedure
      begin
        ListView1.EndUpdate;
        AniIndicator1.Enabled := False;
        AniIndicator1.Visible := False;
      end
    );
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if _loadThread <> nil then
  begin
    _loadThread := TLoadThread.Create;
    _loadThread.OnTerminate := ThreadTerminated;
    _loadThread.Start;
  end;
end;

否则,如果你使用一个线程,不要同步循环本身,只有实际接触UI的部分:

{{1}}