4

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?

HeartWare
  • 7,464
  • 2
  • 26
  • 30
  • There's a demo of adjusting to screen rotations in `C:\Users\Public\Documents\RAD Studio\12.0\Samples\FireMonkeyMobile\Delphi\Forms`. – Ken White Dec 31 '13 at 20:06

3 Answers3

10

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;
blong
  • 2,145
  • 13
  • 23
  • Excellent. Now this works, but it seems like I don't get the proper screen size, but only a 1280x800 screen size (minus menu bar at bottom), even though my tablet is 2560x1600. How can I make Android understand, that I can handle any and all screen sizes (that I adjust my buttons etc. myself), and that it shouldn't apply any scaling, but just allow me to utilize the full screen size? When I read the Screen.Size in my re-flow code, it always return 1280x752 (landscape) or 800x1232 (portrait). – HeartWare Dec 31 '13 at 22:38
  • Addeddum: For easier development, I have made my MainForm use the 1280x800 predefined size. Makes it easier to use the designer. But I still want to be able to use the full size of the target device and do my own scaling and/or reflowing of my controls... – HeartWare Dec 31 '13 at 22:40
  • I think you can get the inherent screen scaling using something like: var ScreenService: IFMXScreenService; Scale: Single; ... if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) then Scale := ScreenService.GetScreenScale else Scale := 1; – blong Jan 01 '14 at 00:23
6

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;
Ivan Revelli
  • 363
  • 4
  • 8
5

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.

Yaroslav Brovin
  • 964
  • 6
  • 19
  • couldn't one figure out the orientation upon OnResize event just be comparing the Form's width to its height? In fact I'd expect all controls to have an Orientation: TOrientation read-only property to return their "orientation" and controls like TrackBars that have different meaning for orientation would implement their own logic there – George Birbilis Jul 09 '22 at 21:05