Two parts to this solution:
Part #1 - It required creating a descendant of the Android View
class that overrides onGenericMotionEvent
, and passes the event to a "delegate". I've added this code to my Kastri library, however I'll repeat them here for completeness:
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);
}
You'll need to compile this Java code into a jar file (e.g. using Android Studio) that you add to the Libraries node under the Android platform in Project Manager in Delphi.
EDIT: In case you have trouble compiling the jar, I've also built one which contains only the code above:
https://github.com/DelphiWorlds/Kastri/blob/master/Lib/dw-genericview.jar
Part #2 - Import for the Java code:
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.
Test project code:
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.
The code creates an instance of the View
descendant, passing the "delegate" reference (that passes the event on to the form code), and adds it to the native layout for the form.
That will get you as far as having an event
instance available. Use the relevant methods of that to work out the delta etc.
GestureDetector
(imported asJGestureDetector
inAndroidapi.JNI.GraphicsContentViewText.pas
), however you will also need to construct a class that descends fromTJavaLocal
that implementsJGestureDetector_OnGestureListener
, and code theonScroll
method of it. I don't have time right now to "fill in the blanks", however I might be able to help if you become stuck – Dave Nottage