我开发的游戏在首次加载时进行了一些预处理,我想向用户显示一个" loading%"明确表示游戏并未冻结。
我正在尝试通过等待主窗体为用户显示,然后在执行预处理时显示更新进度条来实现此目的。
为了使预处理工作,我需要两条信息:
1.表格的最终尺寸(在整个显示屏上最大化)
2.表单对用户可见。
这是一个日志,显示在我的游戏加载时触发的表单事件的顺序。请注意,我并未使用以下任何事件中的代码更改表单的大小:
FormCreate
FormResize, clientSize : 0x0
FormResize, clientSize : 0x0
FormResize, clientSize : 0x0
FormResize, clientSize : 0x0
FormShow
FormActivate
FormResize, clientSize : 360x640
目前,我尝试在最后一次调整大小时显示加载屏幕(指示表单实际上是显示的大小),但此时,主窗体仍然不可见(即使在FormShow和FormActivate之后) )我最终得到了Android的默认"灰色渐变"屏幕显示直到我的预处理代码已经完成,从未显示进度条。
我试过调用" application.processmessages"更新进度条后,但它没有什么区别......
如何检测主要表单何时实际可供Android用户看到?
[更新]
我创建了一个小应用程序来演示这个问题:
https://github.com/bLightZP/Test_Splash
答案 0 :(得分:3)
此示例说明了如何使用OnIdle,以及应该的实现方式。
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Controls.Presentation, FMX.StdCtrls;
type
TForm1 = class(TForm)
ProgressBar1: TProgressBar;
private
FShown: Boolean;
procedure ApplicationOnIdleHandler(Sender: TObject; var Done: Boolean);
procedure ExecutePreProcessing;
procedure ExecutePreProcessingSynchronized;
public
constructor Create(AOwner: TComponent); override;
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
constructor TForm1.Create(AOwner: TComponent);
begin
inherited;
// Method 1: Use OnIdle to execute code when the main form is visible:
Application.OnIdle := ApplicationOnIdleHandler;
// Method 2: Use a thread to execute the preprocessing. Comment out the line above if using this method, and uncomment the line below
// TThread.CreateAnonymousThread(ExecutePreProcessingSynchronized).Start;
end;
procedure TForm1.ApplicationOnIdleHandler(Sender: TObject; var Done: Boolean);
begin
if not FShown then
begin
FShown := True;
ExecutePreProcessing;
end;
end;
procedure TForm1.ExecutePreProcessing;
var
I: Integer;
begin
for I := 1 to 100 do
begin
Sleep(50);
ProgressBar1.Value := I;
Application.ProcessMessages; // <---- Not the best idea
end;
end;
procedure TForm1.ExecutePreProcessingSynchronized;
var
I: Integer;
begin
for I := 1 to 100 do
begin
Sleep(50);
// Ensure UI updates happen in the main thread
TThread.Synchronize(nil,
procedure
begin
ProgressBar1.Value := I;
end
);
end;
end;
end.
答案 1 :(得分:1)
BecameActive事件(ApplicationEvent)怎么样? 使用此文章,使用Google翻译进行翻译 http://delphifmandroid.blogspot.com/2016/09/delphi-android.html
启动应用:
09-20 20:13:43.151: I/info(15893): FMX: Project1: FormCreate
09-20 20:13:43.151: I/info(15893): FMX: Project1: FormResize
09-20 20:13:43.151: I/info(15893): FMX: Project1: FormResize
09-20 20:13:43.161: I/info(15893): FMX: Project1: FormResize
09-20 20:13:43.161: I/info(15893): FMX: Project1: FormShow
09-20 20:13:43.161: I/info(15893): FMX: Project1: FormActivate
09-20 20:13:43.161: I/info(15893): FMX: Project1: Finished Launching
09-20 20:13:43.221: I/info(15893): FMX: Project1: FormPaint
09-20 20:13:43.231: I/info(15893): FMX: Project1: Became Active
09-20 20:13:43.261: I/info(15893): FMX: Project1: FormPaint
09-20 20:13:43.281: I/info(15893): FMX: Project1: FormPaint
09-20 20:13:43.311: I/info(15893): FMX: Project1: FormPaint