使用Delphi 10.2.1 Tokyo的Modal Android Dialog

时间:2017-08-23 09:49:49

标签: android delphi firemonkey

我有以下Delphi代码用于在Android上显示模态消息,该消息在10.1柏林上正常工作,但已停止在Delphi 10.2.1 Tokyo上工作。此过程现在挂起Android应用程序。

procedure customShowMessage(AMessage: string);
//good idea to have our own procedure that we can tweak, as even for VCL and windows, we have done show message differently over the years due to all sorts of funny problems
var
  LModalWindowOpen: boolean;
begin
  LModalWindowOpen := true;

  TDialogService.MessageDialog(AMessage, TMsgDlgType.mtConfirmation, [TMsgDlgBtn.mbOK], TMsgDlgBtn.mbOK, 0,
         procedure(const AResult: TModalResult)
         begin
           LModalWindowOpen := false;
         end);

  while LModalWindowOpen do
    begin
      Application.ProcessMessages; //since 10.2 Tokyo, popup never shows and this loops forever
    end;
end;

我怀疑它可能与东京的变化有关,即应用程序如何在主线程中运行。不知道我可以用它替换Application.ProcessMessages,让对话框显示,以便用户可以点击某些内容。

我有很多地方使用它,因此使用回调将其更改为工作将是很多工作和重组。

3 个答案:

答案 0 :(得分:2)

在Android上,我们只有异步对话框。如果我们想要它们作为模态对话框,我们必须自己做。

使用ProcessMessage循环的解决方案是一个想法,但我不认为这是最好的方法。

另一个是在显示对话框之前在表单上添加透明(或不透明)布局(或矩形),当您有答案时,可以删除阻止布局。

你也可以使用Andrea Magni的TFrameStand(可直接从GetIt下载)如何建议使用TFrame作为对话框。 https://github.com/andrea-magni/TFrameStand

答案 1 :(得分:0)

我认为以下代码应该有效:

function ShowMessageOKCancel(AMessage: String): String;
var
  lResultStr: String;
begin
  lResultStr:='';
  TDialogService.PreferredMode:=TDialogService.TPreferredMode.Platform;
  TDialogService.MessageDialog(AMessage, TMsgDlgType.mtConfirmation,
    FMX.Dialogs.mbOKCancel, TMsgDlgBtn.mbOK, 0,
    procedure(const AResult: TModalResult)
    begin
      case AResult of
        mrOK: lResultStr:='O';
        mrCancel:  lResultStr:='C';
      end;
    end);

  Result:=lResultStr;
end;

当你调用这个函数时,它应该显示一个带有你的消息的对话框,然后是两个按钮OK和Cancel。返回值将指示单击了哪个按钮。

答案 2 :(得分:0)

我已经重构了很多代码来使用异步回调,但是在回调地狱发生的地方(特别是在大型现有项目中),我发现了以下工作:

我现在也在调用CheckSynchronize,而不仅仅是使用Application.ProcessMessages。

procedure TfrmStock.WaitForModalWindowToClose;
begin
  while FModalWindowOpen do
    begin
       Sleep(40);
       Application.ProcessMessages;
       CheckSynchronize;
    end;
end;