【问题标题】:Delphi Android: Can't capture mouse wheel eventsDelphi Android:无法捕获鼠标滚轮事件
【发布时间】:2020-12-30 17:55:43
【问题描述】:

我想在我的 Android 应用程序运行且可见时,在任何情况下随时捕获和处理鼠标滚轮事件。

我这样使用主窗体的事件:

procedure THeaderFooterwithNavigation.FormMouseWheel(Sender: TObject;
  Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean);
begin
  label2.text := inttostr(wheeldelta);
end;

它在应用程序的 Windows 版本中运行良好(Delphi 默认同时为 Android 和 Windows 构建),但在 Android 版本中它似乎什么都不做。

然后我将该过程添加到每个具有相同鼠标滚轮事件的组件中,结果完全相同。

OTG 鼠标滚轮适用于 android 设备、滚动文本窗口等,只有我的 Delphi 应用程序似乎根本不响应鼠标滚轮。

捕获鼠标滚轮事件需要什么?

【问题讨论】:

  • 可能可以通过创建GestureDetector 的实例(在Androidapi.JNI.GraphicsContentViewText.pas 中导入为JGestureDetector)来做到这一点,但是您还需要构造一个继承自TJavaLocal 的类,它实现了JGestureDetector_OnGestureListener,并编写了它的onScroll 方法。我现在没有时间“填空”,但是如果您遇到困难,我可能会提供帮助
  • 删除上面的评论 - 显然这只有在视图的事件被实现时才有效,这似乎是弄巧成拙
  • 目前我正在研究这个解决方案:stackoverflow.com/questions/11024809/…

标签: android delphi firemonkey pascal mousewheel


【解决方案1】:

这个解决方案的两个部分:

第 1 部分 - 它需要创建一个覆盖 onGenericMotionEvent 的 Android View 类的后代,并将事件传递给“委托”。我已将此代码添加到我的 Kastri 库中,但为了完整起见,我将在此处重复它们:

https://github.com/DelphiWorlds/Kastri/blob/master/Java/Base/GenericView/DWGenericView.java

package com.delphiworlds.kastri;

import android.content.Context;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;

public class DWGenericView extends View {

  private DWGenericViewDelegate mDelegate;

  public DWGenericView(Context context, DWGenericViewDelegate delegate) {
    super(context);
    mDelegate = delegate;
  }

  @Override
  public boolean onGenericMotionEvent(MotionEvent event) {
    if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
      switch (event.getAction()) {
        case MotionEvent.ACTION_SCROLL:
          mDelegate.onMouseWheel(event);
          return true;
      }
    }
    return super.onGenericMotionEvent(event);
  }

}

https://github.com/DelphiWorlds/Kastri/blob/master/Java/Base/GenericView/DWGenericViewDelegate.java

package com.delphiworlds.kastri;

import android.view.MotionEvent;

public interface DWGenericViewDelegate {

  public void onMouseWheel(MotionEvent event);

}

您需要将此 Java 代码编译成 jar 文件(例如,使用 Android Studio),然后将其添加到 Delphi 项目管理器中 Android 平台下的 Libraries 节点中。

编辑:如果您在编译 jar 时遇到问题,我还构建了一个仅包含上述代码的 jar:

https://github.com/DelphiWorlds/Kastri/blob/master/Lib/dw-genericview.jar

第 2 部分 - Java 代码的导入:

https://github.com/DelphiWorlds/Kastri/blob/master/API/DW.Androidapi.JNI.DWGenericView.pas

unit DW.Androidapi.JNI.DWGenericView;

interface

uses
  // Android
  Androidapi.JNIBridge, Androidapi.JNI.JavaTypes, Androidapi.JNI.GraphicsContentViewText;

type
  JGenericView = interface;
  JGenericViewDelegate = interface;

  JGenericViewDelegateClass = interface(IJavaClass)
    ['{AF4620B1-9D15-4B8D-82F1-A8A2C1F411DB}']
  end;

  [JavaSignature('com/delphiworlds/kastri/DWGenericViewDelegate')]
  JGenericViewDelegate = interface(IJavaInstance)
    ['{43A4AF5E-4BDB-48E9-9E1F-1F939E4384E4}']
    procedure onMouseWheel(event: JMotionEvent); cdecl;
  end;

  JGenericViewClass = interface(JViewClass)
    ['{9002B46F-C616-4428-8FCA-F86ED28BD55B}']
    {class} function init(context: JContext; delegate: JGenericViewDelegate): JGenericView; cdecl;
  end;

  [JavaSignature('com/delphiworlds/kastri/DWGenericView')]
  JGenericView = interface(JView)
    ['{77A9B1B8-9412-4074-9BBF-FF81F6364174}']
  end;
  TJGenericView = class(TJavaGenericImport<JGenericViewClass, JGenericView>) end;

implementation

end.

测试项目代码:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Memo.Types, FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo,
  Androidapi.JNI.GraphicsContentViewText,
  DW.Androidapi.JNI.DWGenericView;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
  private
    FGenericView: JGenericView;
    FGenericViewDelegate: JGenericViewDelegate;
  protected
    procedure DelegateMouseWheel(event: JMotionEvent);
  public
    constructor Create(AOwner: TComponent); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

uses
  Androidapi.JNIBridge, Androidapi.Helpers,
  FMX.Platform.Android;

type
  TGenericViewDelegate = class(TJavaLocal, JGenericViewDelegate)
  private
    FForm: TForm1;
  public
    { JGenericViewDelegate }
    procedure onMouseWheel(event: JMotionEvent); cdecl;
  public
    constructor Create(AForm: TForm1);
  end;

{ TGenericViewDelegate }

constructor TGenericViewDelegate.Create(AForm: TForm1);
begin
  inherited Create;
  FForm := AForm;
end;

procedure TGenericViewDelegate.onMouseWheel(event: JMotionEvent);
begin
  FForm.DelegateMouseWheel(event);
end;

{ TForm1 }

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  FGenericViewDelegate := TGenericViewDelegate.Create(Self);
  FGenericView := TJGenericView.JavaClass.init(TAndroidHelper.Context, FGenericViewDelegate);
  WindowHandleToPlatform(Handle).FormLayout.addView(FGenericView);
end;

procedure TForm1.DelegateMouseWheel(event: JMotionEvent);
begin
  Memo1.Lines.Add('onMouseWheel: ' + JStringToString(event.toString));
end;

end.

代码创建View后代的实例,传递“委托”引用(将事件传递给表单代码),并将其添加到表单的原生布局中。

这将使您获得可用的event 实例。使用其中的相关方法来计算增量等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    相关资源
    最近更新 更多