How do I detect / handle a screen rotate using FireMonkey for Delphi XE5

11.6k views Asked by At

First of all - I am a beginner when it comes to Android and FireMonkey programming, so please bear this in mind :-).

I have made a FireMonkey/Android application that can resize/reflow its controls according to the screen size and orientation, but I can't figure out how I set my application up to be called, when the user rotates the screen. If I run in it Firemonkey/Win32 and show a button that does the following:

PROCEDURE TMainForm.FlipForm;
  VAR
    W,H : INTEGER;

  BEGIN
    W:=Width; H:=Height; Width:=H; Height:=W
  END;

and then trap the FormResize event, my form resizes/reflows as it should. I would like to do the same when running on Android, but it seems like the FormResize event doesn't get called when the screen rotates, so my buttons etc. is not reflowed and ends up outside the screen.

So my question is, how do I detect that the screen has rotated so that I can have my application work in both Landscape and Portrait mode?

3

There are 3 answers

3
blong On

If you can't get the form's OnResize event to work, then you can subscribe to the FMX orientation changed message thus:

uses
  FMX.Forms, FMX.Messages, FMX.Types;

//In the definition of TFooForm you define:
FOrientationChangedId: Integer;
procedure OrientationChangedHandler(const Sender: TObject; const Msg: TMessage);

//Subscribe to orientation change events in OnCreate or similar
FOrientationChangedId := TMessageManager.DefaultManager.SubscribeToMessage(
  TOrientationChangedMessage, OrientationChangedHandler);

//Unsubscribe from orientation change events in OnDestroy or similar
TMessageManager.DefaultManager.Unsubscribe(
  TOrientationChangedMessage, FOrientationChangedId);

procedure TFooForm.OrientationChangedHandler(const Sender: TObject; const Msg: TMessage);
begin
  Log.d('Orientation has changed');
end;
1
Yaroslav Brovin On

You also can use next approach: When application is rotated, TForm.OnResize is invoked. So you can set handler on this event and check current orientation through service IFMXScreenService.GetScreenOrientation.

0
Ivan Revelli On

to use IFMXScreenService is better test if is supported by the platform, so if isn't supported it generate a "Segmentation Fault" i use it like this:

uses FMXPlatform;

...

procedure TForm2.FormResize(Sender: TObject);
var
  ScreenService: IFMXScreenService;
begin
  if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) then
  begin
    if ScreenService.GetScreenOrientation in [TScreenOrientation.soPortrait, TScreenOrientation.soInvertedPortrait] then
      ShowMessage('Portrait Orientation')
    else
     Begin
      ShowMessage('Landscape Orientation');

     End;

  end;
end;