Когда форма Delphi действительно видна пользователю на Android? - PullRequest
0 голосов
/ 07 июня 2018

Игра, которую я разрабатываю, выполняет некоторую предварительную обработку при первой загрузке, и я хочу показать пользователю «% загрузки», чтобы прояснить, что игра не заморожена.

Я пытаюсьчтобы сделать это, подождите, пока основная форма отобразится для пользователя, а затем отобразите индикатор выполнения обновления при выполнении предварительной обработки.

Чтобы предварительная обработка работала, мне нужно две части информации:
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

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

Как насчет события BecameActive (ApplicationEvent)?Используйте эту статью, переведите ее с помощью Google Translate 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
0 голосов
/ 10 июня 2018

Этот пример иллюстрирует использование 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.
...