Simulating Transparent Dialog on FireMonkey Mobile

by Sep 1, 2017

Delivering great user experience is probably one most important thing in app design. Certain ideas that seem to be easy to achieve in the conceptual phase of development, when an app is still a bunch of wireframes and sketches, could be more difficult to implement then expected.

Today I was helping in providing the "transparent modal dialog" experience to an Android app. The idea is simple. Show the message box on the form and temporarily blur the current content, so the attention of the user is focused on the dialog. This is a Delphi app running on Android. Until Delphi 10.1 this effect could be achieved with displaying the secondary form with transparency enabled, but this approach no longer works in 10.2 due to the internal architectural changes in Android support.

Let me share with you a simple project that shows how to achieve the same visual effect but instead of using transparency, use the "TBlurEffect" and taking the screenshot of the original form.

As the starting point let's use the "MobileControls" demo that comes with RAD Studio installation. This project contains just one form with a TTabControl that shows all kinds of available FireMonkey controls on different tabs. The easiest way to take a screenshot is to call "MakeScreenshot" method that any "TControl" descendant provides. To centralize the process of taking the screenshot add non-visual "TLayout" component to the form and make it a parent of the existing tab control. On top of the screen I have added the toolbar with a button to show the transparent modal form. One more thing is to add the "TBlurEffect" component to the form. Just before taking a screenshot we will enable this effect in code, and disable afterwards. Here is how my main form looks in the Structure view.

Add one more form to the project and put there a TImage component aligned to "Client". In the middle of the form put a TRectangle component and a TButton and a TLabel onto it. In the "OnClick" event of the button enter just call to "Close" the second form. Here is how the second form looks like in the Structure view.

Back to the main form. Add the "Unit2" to the implementation "uses" clause of the form and the following code in the "OnClick" event of the top button:

uses Unit2, FMX.Graphics;

procedure TForm1.btnShowModalClick(Sender: TObject);
var b: TBitmap;
begin
  BlurEffect1.Enabled := True;

  b := Layout1.MakeScreenshot;
  Form2Modal.ImageBackground.Bitmap.Assign(b);
  b.DisposeOf;

  BlurEffect1.Enabled := False;

  Form2Modal.Show;
end

That's it! It works the same way on both Android and iOS. Here are the screenshots from the running app:

     

The nice thing is that it works cross-platform:-)