DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: wjy13061029975
今日帖子: 2
在线用户: 2
导航: 论坛 -> 发布代码 斑竹:liumazi,ruralboy  
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2014/11/18 9:48:39
标题:
7.XE7 安卓模式化对话框及设置是否可以点击对话框区域外面 1.2 浏览:5040
加入我的收藏
楼主: 7. 这开头,看过不看后悔的人家才能理解。

借用 网友的话
没有做不到,只有想不到。

你们总是抱怨 XE7 这不行,那不行。

你们为什么就不去解决下呢?

绕过也可以啊!


注意,下面的代码,缩进有问题。记得 重新排版下。

如果是完整安装的 DELPHI,可以用 CTRL+D 排版。

缩进问题是 盒子 论坛 搞乱了。

修改了一个 BUG 。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2014/11/18 9:49:16
1楼: (* ********** *)
(*          *)
(*  修改:爱吃猪头肉 & Flying Wang 2013-09-19   *)
(*      上面的版权声明请不要移除。      *)
(*          *)
(*          禁止发布到城通网盘。        *)
(*          *)
(* ********** *)

找到安装目录下的 
FMX.Platform.Android.pas
将他们另存到(复制到)其他目录,例如您的工程目录。

将新复制出的文件加入到您的工程中。

【第一步】
打开 FMX.Platform.Android.pas

添加如下信息
(* ********** *)
(*          *)
(*  修改:爱吃猪头肉 & Flying Wang 2013-09-19   *)
(*      上面的版权声明请不要移除。      *)
(*          *)
(*          禁止发布到城通网盘。        *)
(*          *)
(* ********** *)
这是我的版权,请您尊重下。



【第二步】 找到 implementation
在 implementation 之前添加如下内容
//Add By Flying Wang
var
  /// <summary>
  ///   <para>
  ///     是否允许点击对话框区域之外
  ///   </para>
  ///   <para>
  ///     对于默认返回值为 mbHelp 或错误默认值的对话框,本选项无效,肯定禁止
  ///   </para>
  /// </summary>
  MessageDialog_CanceledOnTouchOutsid: Boolean = True;
  /// <summary>
  ///   <para>
  ///     是否允许用返回按钮取消对话框
  ///   </para>
  ///   <para>
  ///     对于默认返回值为 mbHelp 或错误默认值的对话框,本选项无效,肯定禁止
  ///   </para>
  ///   <para>
  ///     目前不起作用
  ///   </para>
  ///   <para>
  ///     也可能是用来决定是否在右上角显示一个关闭按钮。
  ///   </para>
  /// </summary>
  MessageDialog_Canceleable: Boolean = True;

  /// <summary>
  ///   模式化(Modaled or Blocking)对话框内部用等待毫秒数
  /// </summary>
  BlockingMessageWaitMilliSeconds: Integer = 5;

/// <summary>
///   Show a bocking message box
/// </summary>
procedure ShowMessageWait(const AMessage: string);


【第三步】 在 implementation  之后 的 uses 之后添加如下内容
procedure ShowMessageWait(const AMessage: string);
var
  RetVal: Integer;
begin
  RetVal := MessageDlg(AMessage, TMsgDlgType.mtCustom, [TMsgDlgBtn.mbOK], 0,
    //故意设置这个错误的默认值
    System.UITypes.TMsgDlgBtn.mbHelp);
end;


【第四步】 找到 TFMXDialogListener = class(TJavaLocal, JFMXDialogListener)
修改这个类的定义代码,改成如下内容。
//Fix By Flying Wang
  TFMXDialogListener = class(TJavaLocal, JFMXDialogListener)
  private
    [Weak] FParentList: TList<TFmxDialogListener>;
    FValues: array of string;
    FDefaultButtonIndex: Integer;
    FModalResult: TModalResult;
    FInputCloseQueryProc: TInputCloseQueryProc;
    procedure DoDialogClosed;
    procedure SetParentList(const AList: TList<TFmxDialogListener>);
  public
    constructor Create(const AInputCloseQueryProc: TInputCloseQueryProc;
      ADefaultButtonIndex: Integer);
    procedure onDialogClosed(modalResult: Integer; values: TJavaObjectArray<JString>); cdecl;
    property ParentList: TList<TFmxDialogListener> read FParentList write SetParentList;
  end;

【第五步】 找到 
function TPlatformAndroid.MessageDialog(const AMessage: string; const ADialogType: TMsgDlgType;
  const AButtons: TMsgDlgButtons;  const ADefaultButton: TMsgDlgBtn; const AX, AY: Integer; const AHelpCtx: LongInt;
  const AHelpFileName: string): Integer;
修改这个函数的代码,改成如下内容。
//Fix By Flying Wang
function TPlatformAndroid.MessageDialog(const AMessage: string; const ADialogType: TMsgDlgType;
  const AButtons: TMsgDlgButtons;  const ADefaultButton: TMsgDlgBtn; const AX, AY: Integer; const AHelpCtx: LongInt;
  const AHelpFileName: string): Integer;
var
  ARetVal: Integer;
begin
  //raise ENotImplemented.CreateFmt(SNotImplementedOnPlatform, [SBlockingDialogs]);
  Result := -1;
  ARetVal := -1;
  MessageDialog(AMessage, ADialogType, AButtons, ADefaultButton, AX, AY, AHelpCtx, AHelpFileName,
    procedure(const AResult: TModalResult)
      begin
        ARetVal := AResult;
      end);
  while ARetVal < 0 do
  begin
    Sleep(BlockingMessageWaitMilliSeconds);
    Application.ProcessMessages;
  end;
  Result := ARetVal;
end;


【第六步】 找到 
procedure TPlatformAndroid.MessageDialog(const AMessage: string; const ADialogType: TMsgDlgType;
  const AButtons: TMsgDlgButtons;  const ADefaultButton: TMsgDlgBtn; const AX, AY: Integer; const AHelpCtx: LongInt;
  const AHelpFileName: string; const ACloseDialogProc: TInputCLoseDialogProc);
修改这个函数的代码,改成如下内容。
//Fix By Flying Wang
procedure TPlatformAndroid.MessageDialog(const AMessage: string; const ADialogType: TMsgDlgType;
  const AButtons: TMsgDlgButtons;  const ADefaultButton: TMsgDlgBtn; const AX, AY: Integer; const AHelpCtx: LongInt;
  const AHelpFileName: string; const ACloseDialogProc: TInputCLoseDialogProc);
var
  DialogFactory: JFMXDialogFactory;
  DialogListener: TFMXDialogListener;
  AlertDialog: JFMXStandardDialog;
  PosButton, NegButton, NeutralButton: Integer;
  B: TMsgDlgBtn;
  DefaultButton,
  ButtonIndex: Integer;
  ButtonsCount: Integer;
  LCaptions: TJavaObjectArray<JString>;
begin
  ButtonsCount := 0;
  ButtonIndex := 0;
  PosButton := -1;
  NegButton := -1;
  NeutralButton := -1;
  //这里不能用 -1;
  DefaultButton := 0;

  for B in AButtons do
    Inc(ButtonsCount);
  ButtonsCount := Min(ButtonsCount, 3);

  LCaptions := TJavaObjectArray<JString>.Create(ButtonsCount);

  for B in AButtons do
  begin
    if ButtonIndex < ButtonsCount then
    begin
      LCaptions.Items[ButtonIndex] := StringToJString(ButtonCaptions[B]);
      if ADefaultButton = B then
      begin
        DefaultButton := ModalResults[B];
      end;
      case ButtonIndex of
        0: PosButton := ModalResults[B];
        1: NegButton := ModalResults[B];
        2: NeutralButton := ModalResults[B];
      end;
    end;
    Inc(ButtonIndex);
  end;

  DialogFactory := TJFMXDialogFactory.JavaClass.getFactory;
  if DialogFactory <> nil then
  begin
    CallInUIThreadAndWaitFinishing(
      procedure
      begin
        AlertDialog := DialogFactory.createMessageDialog(MainActivity, GetNativeTheme, StringToJString(AMessage),
          Ord(ADialogType), LCaptions, PosButton, NegButton, NeutralButton);

        if AlertDialog <> nil then
        begin
          if DefaultButton > 0 then
          begin
          AlertDialog.getRealDialog.setCancelable(MessageDialog_Canceleable);
          AlertDialog.getRealDialog.setCanceledOnTouchOutside(
          MessageDialog_CanceledOnTouchOutsid);
          end
          else
          begin
          AlertDialog.getRealDialog.setCancelable(False);
          AlertDialog.getRealDialog.setCanceledOnTouchOutside(False);
          end;
          if Assigned(ACloseDialogProc) then
          begin
          DialogListener := TFMXDialogListener.Create(
          procedure (const AResult: TModalResult; const AValues: array of string)
          begin
          ACloseDialogProc(AResult);
          end, DefaultButton);
          DialogListener.ParentList := FAlertListeners;
          AlertDialog.setListener(DialogListener);
          end;
          AlertDialog.show;
        end;
      end);
  end;
end;



【第七步】 找到 
function TPlatformAndroid.InputQuery(const ACaption: string; const APrompts: array of string;
  var AValues: array of string; const ACloseQueryFunc: TInputCloseQueryFunc): Boolean;
修改这个函数的代码,改成如下内容。
//Fix By Flying Wang
function TPlatformAndroid.InputQuery(const ACaption: string; const APrompts: array of string;
  var AValues: array of string; const ACloseQueryFunc: TInputCloseQueryFunc): Boolean;
var
  ARetVal: Integer;
  I, J: Integer;
  CValues: array of string;
begin
  //raise ENotImplemented.CreateFmt(SNotImplementedOnPlatform, [SBlockingDialogs]);
  Result := False;
  ARetVal := -1;
  InputQuery(ACaption, APrompts, AValues,
    procedure(const AResult: TModalResult; const BValues: array of string)
      var
        I, J: Integer;
        AStr: string;
      begin
        ARetVal := AResult;
        if ARetVal = mrOK then
        begin
          if Assigned(ACloseQueryFunc) then
          ACloseQueryFunc(BValues);
          SetLength(CValues, Length(BValues));
          for I := Low(BValues) to High(BValues) do
          begin
          J := Low(CValues) + I - Low(BValues);
          if J <= High(CValues) then
          CValues[J] := BValues[I];
          end;
        end;
      end);
  while ARetVal < 0 do
  begin
    Sleep(BlockingMessageWaitMilliSeconds);
    Application.ProcessMessages;
  end;
  Result := ARetVal = mrOK;
  if Result then
  begin
    for I := Low(CValues) to High(CValues) do
    begin
      J := Low(AValues) + I - Low(AValues);
      if J <= High(AValues) then
        AValues[J] := CValues[I];
    end;
  end;
end;


【第八步】 找到 
procedure TPlatformAndroid.InputQuery(const ACaption: string; const APrompts, ADefaultValues: array of string;
  const ACloseQueryProc: TInputCloseQueryProc);
修改这个函数的代码,改成如下内容。
//Fix By Flying Wang
procedure TPlatformAndroid.InputQuery(const ACaption: string; const APrompts, ADefaultValues: array of string;
  const ACloseQueryProc: TInputCloseQueryProc);
var
  DialogFactory: JFMXDialogFactory;
  QueryDialog: JFMXStandardDialog;
  JavaPrompts: TJavaObjectArray<JString>;
  JavaDefaultValues: TJavaObjectArray<JString>;
  DialogListener: TFMXDialogListener;
  LCaptions: TJavaObjectArray<JString>;
  I: Integer;
begin
  if Length(ADefaultValues) < Length(APrompts) then
    raise EInvalidOperation.Create(SPromptArrayTooShort);
  if Length(APrompts) = 0 then
    raise EInvalidOperation.Create(SPromptArrayEmpty);

  JavaPrompts := TJavaObjectArray<JString>.Create(Length(APrompts));
  JavaDefaultValues := TJavaObjectArray<JString>.Create(Length(ADefaultValues));
  for I := 0 to Length(APrompts) - 1 do
    JavaPrompts[I] := StringToJString(APrompts[I]);
  for I := 0 to Length(ADefaultValues) - 1 do
    JavaDefaultValues[I] := StringToJString(ADefaultValues[I]);
  LCaptions := TJavaObjectArray<JString>.Create(2);
  LCaptions.Items[0] := StringToJString(ButtonCaptions[TMsgDlgBtn.mbOK]);
  LCaptions.Items[1] := StringToJString(ButtonCaptions[TMsgDlgBtn.mbCancel]);
  DialogFactory := TJFMXDialogFactory.JavaClass.getFactory;
  if DialogFactory <> nil then
  begin
    CallInUIThreadAndWaitFinishing(
      procedure
        begin
          QueryDialog := DialogFactory.createInputQueryDialog(MainActivity, GetNativeTheme, StringToJString(ACaption),
          JavaPrompts, JavaDefaultValues, LCaptions);
          if QueryDialog <> nil then
          begin
          QueryDialog.getRealDialog.setCancelable(MessageDialog_Canceleable);
          QueryDialog.getRealDialog.setCanceledOnTouchOutside(
          MessageDialog_CanceledOnTouchOutsid);
          if Assigned(ACloseQueryProc) then
          begin
          DialogListener := TFMXDialogListener.Create(ACloseQueryProc,
          ModalResults[TMsgDlgBtn.mbCancel]);
          DialogListener.ParentList := FAlertListeners;
          QueryDialog.setListener(DialogListener);
          end;
          QueryDialog.show;
          end;
        end);
  end;
end;

【第九步】 找到 
constructor TFMXDialogListener.Create(const AInputCloseQueryProc: TInputCloseQueryProc;
      ADefaultButtonIndex: Integer); 和 procedure TFMXDialogListener.DoDialogClosed;
修改这两个函数的代码,改成如下内容。

//Fix By Flying Wang.
constructor TFMXDialogListener.Create(const AInputCloseQueryProc: TInputCloseQueryProc;
      ADefaultButtonIndex: Integer);
begin
  inherited Create;
  FDefaultButtonIndex := ADefaultButtonIndex;
  FInputCloseQueryProc := AInputCloseQueryProc;
end;

//Fix By Flying Wang.
procedure TFMXDialogListener.DoDialogClosed;
begin
  //非常幸运的是,正常的返回都大于 0 。
  if FModalResult <= 0 then
    FModalResult := FDefaultButtonIndex;
  FInputCloseQueryProc(FModalResult, FValues);
  if FParentList <> nil then
    FParentList.Remove(Self);
  FParentList := nil;
end;
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2014/11/18 9:49:32
2楼: 【使用方法】

//Add By Flying Wang.
procedure ShowMessageWait(const AMessage: string);
var
  RetVal: Integer;
begin
{$IFDEF ANDROID}
  FMX.Platform.Android.ShowMessageWait(AMessage);
{$ELSE}
  ShowMessage(AMessage);
{$ENDIF ANDROID}
end;

procedure TMessageAlertsForm.btnStandardAlertClick(Sender: TObject);
begin
  //Fix By Flying wang
{$IFDEF ANDROID}
  MessageDialog_CanceledOnTouchOutsid := CheckBox1.IsChecked;
  MessageDialog_Canceleable := CheckBox2.IsChecked;
{$ENDIF ANDROID}
  ShowMessageWait('还有一个对话框');
  ShowMessageWait('Hello World!' + sLineBreak + 'Test Other Button.');
end;


//下面的两个例子,也可以改造成 BLOCKING 模式,并且可以不使用匿名函数。
procedure TMessageAlertsForm.btnMultiButtonAlertClick(Sender: TObject);
begin
  //Fix By Flying wang
{$IFDEF ANDROID}
  MessageDialog_CanceledOnTouchOutsid := CheckBox1.IsChecked;
  MessageDialog_Canceleable := CheckBox2.IsChecked;
{$ENDIF ANDROID}
  MessageDlg('Choose a button:', System.UITypes.TMsgDlgType.mtInformation,
    [
      System.UITypes.TMsgDlgBtn.mbYes,
      System.UITypes.TMsgDlgBtn.mbNo,
      System.UITypes.TMsgDlgBtn.mbCancel
    ], 0, System.UITypes.TMsgDlgBtn.mbCancel,
    procedure(const AResult: TModalResult)
    begin
      if AResult = mrYES then
         ShowMessage('You chose Yes') else
      if AResult = mrNo then
         ShowMessage('You chose No') else
      if AResult = mrCancel then
         ShowMessage('You chose Cancel');
      end);
end;

//Add By Flying Wang.
procedure TMessageAlertsForm.ButtonInputQueryClick(Sender: TObject);
var
  AString: string;
begin
  AString := 'Old string';
  //Fix By Flying wang
{$IFDEF ANDROID}
  MessageDialog_CanceledOnTouchOutsid := CheckBox1.IsChecked;
  MessageDialog_Canceleable := CheckBox2.IsChecked;
{$ENDIF ANDROID}
  InputBox('输入对话框',
    'Input a text:', AString,
    procedure(const AResult: TModalResult; const AValue: string)
    begin
      AString := AValue;
      if AResult = mrOK then
         ShowMessage('Youer input text is:' + AString) else
      if AResult = mrCancel then
         ShowMessage('You chose Cancel');
    end);

end;
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2014/11/18 9:50:01
3楼: 你们看看,代码复杂吗,你们为什么就不能自己做到?

建议不要用 BLOCK 模式,影响效率。

下面赠送

6.XE7 修复 安卓 输入法隐藏 后 无法退出的问题 3.3.txt

的内容。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2014/11/18 9:50:20
4楼: (**********)
(*          *)
(*     编写:爱吃猪头肉 & Flying Wang     *)
(*      上面的版权声明请不要移除。      *)
(*          2014-04-16          *)
(*          *)
(*          禁止发布到城通网盘。        *)
(*          *)
(**********)


找到安装目录下的 
FMX.VirtualKeyboard.Android
将他们另存到(复制到)其他目录,例如您的工程目录。

将新复制出的文件加入到您的工程中。

【第一步】
打开 FMX.VirtualKeyboard.Android 找到
function TVirtualKeyboardAndroid.GetVirtualKeyboardState: TVirtualKeyboardStates;
begin
  if FError then
    Result := [TVirtualKeyboardState.Error]
  else
    Result := [];
  if IsAutoShow then
    Result := Result + [TVirtualKeyboardState.AutoShow];
  if FTransient then
    Result := Result + [TVirtualKeyboardState.Transient];
  if not FError then
  begin
    if FState = TvkbState.Shown then
      Result := Result + [TVirtualKeyboardState.Visible];
  end;
end;


将上面的函数修改为
//Fix Error By 爱吃猪头肉 & Flying Wang
function ObtainKeyboardRect: TRect;
var
  ContentRect, TotalRect: JRect;
begin
  ContentRect := TJRect.Create;
  TotalRect := TJRect.Create;
  MainActivity.getWindow.getDecorView.getWindowVisibleDisplayFrame(ContentRect);
  MainActivity.getWindow.getDecorView.getDrawingRect(TotalRect);
  Result := TRectF.Create(ConvertPixelToPoint(TPointF.Create(TotalRect.left, TotalRect.top + ContentRect.height)),
    ConvertPixelToPoint(TPointF.Create(TotalRect.right, TotalRect.bottom))).Truncate;
end;

function GetVirtualKeyboardHeight: Single;
var
  KeyboardRect: TRect;
begin
  Result := 0;
  KeyboardRect := ObtainKeyboardRect;
  //目前设置为 低于 30 就算隐藏。
  if (KeyboardRect.Width < 30) or (KeyboardRect.Height < 30) then
  begin
    exit;
  end;
  Result := KeyboardRect.Height;
end;

procedure ProcessVirtualKeyboardEvent;
var
  VirtualKeyboard: IFMXVirtualKeyboardService;
  VirtualKeyboardAndroid: TVirtualKeyboardAndroid;
begin
  if TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService,
    IInterface(VirtualKeyboard)) then
  begin
    VirtualKeyboardAndroid := TVirtualKeyboardAndroid(VirtualKeyboard);
    VirtualKeyboardAndroid.GetVirtualKeyBoardState;
  end;
end;

function HideInputForFixVirtualKeyboardEvent :Boolean;
var
  TextView: JFMXTextEditorProxy;
begin
  Result := False;
  try
    Screen.ActiveForm.Focused := nil;
    TextView := MainActivity.getTextEditorProxy;
      CallInUIThread(
        procedure
        begin
          TextView.setFocusable(false);
          TextView.setFocusableInTouchMode(false);
        end);
      Result := True;
  except
    Application.HandleException(Screen.ActiveForm);
  end;
end;

function TVirtualKeyboardAndroid.GetVirtualKeyboardState: TVirtualKeyboardStates;
var
  KeyboardRect: TRect;
begin
  if FError then
    Result := [TVirtualKeyboardState.Error]
  else
    Result := [];
  if IsAutoShow then
    Result := Result + [TVirtualKeyboardState.AutoShow];
  if FTransient then
    Result := Result + [TVirtualKeyboardState.Transient];
  if not FError then
  begin
    if (FState = TvkbState.Shown) then
    begin
      if GetVirtualKeyboardHeight < 1 then
      begin
        KeyboardRect := ObtainKeyboardRect;
        TThread.Synchronize(nil,
          procedure
          begin
          SetState(TVirtualKeyboardAndroid.TvkbState.Hidden);
          TMessageManager.DefaultManager.SendMessage(Self, TVKStateChangeMessage.Create(false, ObtainKeyboardRect), True);
          end);
        end;
    end;
    if FState = TvkbState.Shown then
      Result := Result + [TVirtualKeyboardState.Visible];
  end;
end;

缺点:我的山寨机上 26 的高度就没有输入法了。但是不知道其他的机器是多少。
事实上,只检查高度就可以,为了安全起见,才 高度 宽度 都检查的。


【第二步】
然后到 文件的前面(implementation 之前),定义


///  <summary>
///    When < 1, it means VirtualKeyBoard Hided.
///  </summary>
function GetVirtualKeyBoardHeight: Single;

///  <summary>
///    <para>
///      Use a timer to call me. it will fix VirtualKeyboard Hide Message.
///    </para>
///    <para>
///      用一个 TIMER 调用本函数,可以修复虚拟键盘的隐藏消息。建议虚拟键盘显示后启用 TIMER。
///    </para>
///  </summary>
procedure ProcessVirtualKeyboardEvent;

///  <summary>
///    强制输入控件隐藏输入。
///  </summary>
function HideInputForFixVirtualKeyboardEvent :Boolean;







下面是【使用方法】。

1. 放一个 Timer 例如叫 TimerForVKeyboard。300ms 一次。
procedure TForm1.TimerForVKeyboardTimer(Sender: TObject);
begin
{$IFDEF ANDROID}
  ProcessVirtualKeyboardEvent;
{$ENDIF}
end;


2. 完成如下事件。其实完全可以对每个输入框的按下事件处理。参考 4 。
procedure TForm1.FormVirtualKeyboardHidden(Sender: TObject; KeyboardVisible: Boolean; const Bounds: TRect);
begin
  //键盘不显示了,Timer 就休息吧。
  TimerForVKeyboard.Enabled := False;
  Memo1.Lines.Add('键盘隐藏了');
  Memo1.GoToTextEnd;
//  Focused := nil; //如果不想继续输入了,可以设置这个。
//{$IFDEF ANDROID}
//  HideInputForFixVirtualKeyboardEvent;
//{$ENDIF}
end;

3. 完成如下事件。
procedure TForm1.FormVirtualKeyboardShown(Sender: TObject; KeyboardVisible: Boolean; const Bounds: TRect);
begin
  //键盘出来了,Timer 要工作了。
  TimerForVKeyboard.Enabled := True;
  Memo1.Lines.Add('键盘显示了');
  Memo1.GoToLineEnd;
end;

4 或者对每个输入框的按下事件处理。
uses
  FMX.Platform,
  FMX.VirtualKeyboard;
//使用这个事件
procedure TForm1.Edit1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
var
  VirtualKeyboard: IFMXVirtualKeyboardService;
begin
{$IFDEF ANDROID}
  if GetVirtualKeyboardHeight < 1 then
  begin
    if TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyboardService,
      IInterface(VirtualKeyboard)) then
    begin
      if not (TVirtualKeyboardState.Visible in VirtualKeyboard.VirtualKeyBoardState) then
      begin
        if (TVirtualKeyboardState.AutoShow in VirtualKeyboard.VirtualKeyBoardState) then
          VirtualKeyboard.ShowVirtualKeyboard(Edit1);
      end;
    end;
  end;
{$ENDIF}
end;
----------------------------------------------
(C)(P)Flying Wang
作者:
男 gaoyong_gy (gaoyong_gy) ★☆☆☆☆ -
盒子活跃会员
2014/11/18 10:00:01
5楼: 猫猫是个好人。
----------------------------------------------
Delphi 的移动程序开发,是您不可再错失的机遇:http://blog.163.com/you888@188/blog/static/6723961920169319529515/
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2014/11/18 13:22:35
6楼: 下面做了修改
【第九步】 找到 
constructor TFMXDialogListener.Create(const AInputCloseQueryProc: TInputCloseQueryProc 
和 procedure TFMXDialogListener.DoDialogClosed;
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2014/11/18 13:23:03
7楼: 【使用方法】也修改一下。

//Add By Flying Wang.
procedure ShowMessageWait(const AMessage: string);
var
  RetVal: Integer;
begin
{$IFDEF ANDROID}
  FMX.Platform.Android.ShowMessageWait(AMessage);
{$ELSE}
  ShowMessage(AMessage);
{$ENDIF ANDROID}
end;

procedure TMessageAlertsForm.btnStandardAlertClick(Sender: TObject);
begin
  //Fix By Flying wang
{$IFDEF ANDROID}
  MessageDialog_CanceledOnTouchOutsid := CheckBox1.IsChecked;
  MessageDialog_Canceleable := CheckBox2.IsChecked;
{$ENDIF ANDROID}
  ShowMessageWait('还有一个对话框');
  ShowMessageWait('Hello World!' + sLineBreak + 'Test Other Button.');
end;

procedure TMessageAlertsForm.btnMultiButtonAlertClick(Sender: TObject);
var
  BResult: TModalResult;
begin
  //Fix By Flying wang
{$IFDEF ANDROID}
  MessageDialog_CanceledOnTouchOutsid := CheckBox1.IsChecked;
  MessageDialog_Canceleable := CheckBox2.IsChecked;
{$ENDIF ANDROID}
//  MessageDlg('Choose a button:', System.UITypes.TMsgDlgType.mtInformation,
//    [
//      System.UITypes.TMsgDlgBtn.mbYes,
//      System.UITypes.TMsgDlgBtn.mbNo,
//      System.UITypes.TMsgDlgBtn.mbCancel
//    ], 0, System.UITypes.TMsgDlgBtn.mbCancel,
//    procedure(const AResult: TModalResult)
//    begin
//      if AResult = mrYES then
//         ShowMessage('You chose Yes') else
//      if AResult = mrNo then
//         ShowMessage('You chose No') else
//      if AResult = mrCancel then
//         ShowMessage('You chose Cancel');
//      end);
  //上面是非模式化的,下面是模式化的。
  BResult := MessageDlg('Choose a button:', System.UITypes.TMsgDlgType.mtInformation,
    [
      System.UITypes.TMsgDlgBtn.mbYes,
      System.UITypes.TMsgDlgBtn.mbNo,
      System.UITypes.TMsgDlgBtn.mbCancel
    ], 0, System.UITypes.TMsgDlgBtn.mbCancel);

      if BResult = mrYES then
         ShowMessage('You chose Yes') else
      if BResult = mrNo then
         ShowMessage('You chose No') else
      if BResult = mrCancel then
         ShowMessage('You chose Cancel');
end;

//Add By Flying Wang.
procedure TMessageAlertsForm.ButtonInputQueryClick(Sender: TObject);
var
  AString: string;
  BResult: TModalResult;
begin
  AString := 'Old string';
  //Fix By Flying wang
{$IFDEF ANDROID}
  MessageDialog_CanceledOnTouchOutsid := CheckBox1.IsChecked;
  MessageDialog_Canceleable := CheckBox2.IsChecked;
{$ENDIF ANDROID}
//  InputBox('输入对话框',
//    'Input a text:', AString,
//    procedure(const AResult: TModalResult; const AValue: string)
//    begin
//      AString := AValue;
//      if AResult = mrOK then
//         ShowMessage('Youer input text is:' + AString) else
//      if AResult = mrCancel then
//         ShowMessage('You chose Cancel');
//    end);
  //上面是非模式化的,下面是模式化的。
  if InputQuery('输入对话框','Input a text:', AString) then
    ShowMessage('Youer input text is:' + AString)
  else
    ShowMessage('You chose Cancel');

end;
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2014/11/18 14:54:24
8楼: 关于输入框被输入法遮挡。
请打开你的 计算机,打开开始菜单。找到 samples 。从里头找一个 DEMO。有代码解决。

EMB 不是白痴,这种低级问题,人家早就解决了。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 delphi_liang (露露) ▲▲▲▲▲ -
普通会员
2014/11/20 16:46:07
9楼: To  :Flying Wang 你辛苦了,我这种菜鸟很需要上边的代码。。。。。
----------------------------------------------
delphi菜鸟一只~~~
作者:
男 lsuper (lsuper) ★☆☆☆☆ -
盒子活跃会员
2014/11/23 17:09:21
10楼: to wang_80919 (Flying Wang):赞一个!建议提供 diff 文件,方便大家直接 merge ~
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2014/12/8 22:15:04
11楼: 特别声明
禁止 qiuyan81 (苦恋树) QQ46494153 使用本人修改的内容。

禁止 gfuchao  QQ82715485 使用本人修改的内容。

禁止 supersk QQ未知,使用本人修改的版本。


当然,如果你们脸皮比较厚,就偷偷的用吧。

凡是想要骂我的,都可以偷偷的用,反正我是控制不了。
只要你们不鄙视自己就行。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2015/1/20 13:24:39
12楼: 修改下对 IOS 的模式化支持。

//Add By Flying Wang.
procedure ShowMessagePosWait(const AMessage: string; const AX, AY: Integer);
begin
{$IFDEF ANDROID}
  MessageDlgPosHelp(AMessage, TMsgDlgType.mtCustom, [TMsgDlgBtn.mbOK], 0, AX, AY, '',
    //故意设置这个错误的默认值
    System.UITypes.TMsgDlgBtn.mbHelp);
{$ELSE}
  MessageDlgPos(AMessage, TMsgDlgType.mtCustom, [TMsgDlgBtn.mbOK], 0, AX, AY);
{$ENDIF ANDROID}
end;

//用这个函数,在各个平台下都会模式化。


//Add By Flying Wang.
procedure ShowMessageWait(const AMessage: string);
begin
  ShowMessagePosWait(AMessage, -1, -1);
end;

//Add By Flying Wang.
procedure ShowMessageFmtWait(const AMessage: string; const AParams: array of const);
begin
  ShowMessageWait(Format(AMessage, AParams));
end;


资料来源
[龟山]阿卍(1467948783)  13:15:43
http://docwiki.embarcadero.com/Libraries/XE7/en/FMX.Dialogs.MessageDlg
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2015/3/15 19:06:43
13楼: 特别声明
禁止 qiuyan81 (苦恋树) QQ46494153 使用本人修改的内容。

禁止 gfuchao  QQ82715485 使用本人修改的内容。

禁止 supersk QQ未知,使用本人修改的版本。

禁止 [北京]屌丝(28493389),使用本人修改的版本。


当然,如果你们脸皮比较厚,就偷偷的用吧。

凡是想要骂我的,都可以偷偷的用,反正我是控制不了。
只要你们不鄙视自己就行。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2015/3/30 10:13:23
14楼: 现在还没时间测试这些修改。

争取 周末 测试完。
----------------------------------------------
(C)(P)Flying Wang
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行167.9688毫秒 RSS