B4A Library [Lib] Gesture Detector

This library adds the detection of standard gestures (press, single-tap, double-tap, long tap, drag, scroll, fling, pinch, rotation) to B4A. Instead of using the Touch events to figure out what the user really did, now you just set 15 different listeners with one line of code and you get the gestures as events with all the useful values (scrolling distance, fling velocity, pinch variation, rotation angle...).
With this library, you can also know easily the pressure or the size of a touch event.

It works with any view.

Note: you have to create an instance of GestureDetector (with Dim) for each view you want to bind to the detector with SetOnGestureListener.

v2.2:
- Freeware.

v2.3:
- I fixed an issue with the boolean value returned by the OnTouch event with some views (e.g. ListView or ScrollView);
- I added a new demo (GD_SwipeLV);
- The OnDown event is now raised before OnDoubleTap.

v2.4:
- I fixed an issue when a view is dragged after one of the pointer is up (delta values were computed according to the pointer 0, not to the remaining pointer).

Incompatible with Android versions < 2.
 

Attachments

  • GestureDetector v2.4.zip
    35.3 KB · Views: 3,316
  • Java source - GestureDetector.zip
    5.5 KB · Views: 1,355
Last edited:

Informatix

Expert
Licensed User
Longtime User
Hello Informatix,

I try to use "onLongPress" event.
This event work, but when I want to use it to show preference screen, I obtain following error :
B4X:
java.lang.NullPointerException
    at flm.b4a.gesturedetector.GestureDetectorForB4A$1.onTouch(GestureDetectorForB4A.java:89)
    at android.view.View.dispatchTouchEvent(View.java:7345)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2464)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2151)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1480)
    at android.app.Activity.dispatchTouchEvent(Activity.java:2469)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2099)
    at android.view.View.dispatchPointerEvent(View.java:7535)
    at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3492)
    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3424)
    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4534)
    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4512)
    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4616)
    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
    at android.os.MessageQueue.nativePollOnce(Native Method)
    at android.os.MessageQueue.next(MessageQueue.java:125)
    at android.os.Looper.loop(Looper.java:124)
    at android.app.ActivityThread.main(ActivityThread.java:4921)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
    at dalvik.system.NativeStart.main(Native Method)

Have you some explanations or advises ?

Regards
??? Could you send me some code to test? Or a snippet to code helping to reproduce the error?
 

kiki78

Active Member
Licensed User
Longtime User
I make small very small application that reproduce error.

Thank you for your support.

Regards
 

Attachments

  • TestGest.zip
    8.4 KB · Views: 313

Informatix

Expert
Licensed User
Longtime User
I make small very small application that reproduce error.

Thank you for your support.

Regards
I cannot test your application because I don't have B4A 3.2 on my PC but I was able to reproduce the issue. I have no immediate explanation. I try to understand what's going on. It seems it's related to the preferences screen.

EDIT: ok, it's due to the preferences screen. When you long press the panel, you start a new activity. When you lift your finger, a new touch event is fired but the activity has changed, hence the error. Solution: none for now. I have to update the library to add a function to remove the listener.
 
Last edited:

johndb

Active Member
Licensed User
Longtime User
I have begun implementing this library (donated) in one of my projects. I am using the "PointerUp" event to detect when gesture events have completed. The PointerUp event is fired after OnPinchOpen & OnPinchClose however the PointerUp event is not fired after the "OnDrag" event once the finger is lifted from the display. Could you please add the PointerUp event once the finger has been lifted after onDrag?

Thanks,

John
 

CapReed

Member
Licensed User
Longtime User
Hello!

I have a scrollview and I want to control the movements you make on the SV.

To do this I have set up a transparent panel over, and I want to transfer the movements that are made on transparent panel to the scrollview.

Can you do this with the library, to transfer the movements of the this transparent panel to ScrollView, or you can just transfer the touch panel from transparent to what is underneath?

Really what I want is to know the movements that are made on the scrollview and the scrollview while move normally.

Maybe there is some more easily.

Thank you.

P.D. Excuse my horrous english, please ...
 

CapReed

Member
Licensed User
Longtime User
Hello!

I have a scrollview and I want to control the movements you make on the SV.

To do this I have set up a transparent panel over, and I want to transfer the movements that are made on transparent panel to the scrollview.

Can you do this with the library, to transfer the movements of the this transparent panel to ScrollView, or you can just transfer the touch panel from transparent to what is underneath?

Really what I want is to know the movements that are made on the scrollview and the scrollview while move normally.

Maybe there is some more easily.

Thank you.

P.D. Excuse my horrous english, please ...




Good again

I've already managed to solve re-reading all posts.

I leave it here in case it helps some other partner.

Thank you!

This is my solutions :

B4X:
.
.
.
.

ScrollViewEjemplo.Initialize2(100%y,"ScrollViewEjemplo")
MainPanel.AddView(ScrollViewEjemplo,0,0,100%x,81.8%y)
ScrollViewEjemplo.color=Colors.Transparent

paneltransparente.Initialize("")
paneltransparente.Color=Colors.argb(50,170,90,156)
paneldellamadas.AddView(paneltransparente,0,0,100%x,81.8%y)
GD_PS.SetOnGestureListener(paneltransparente, "GD_PS")

.
.
.
.
.


Sub GD_PS_onscroll(distanceX As Float, distanceY As Float, MotionEvent1 As Object, MotionEvent2 As Object)
    Log("  onScroll distanceX = " & distanceX & ", distanceY = " & distanceY & ", ev1 = " & MotionEvent1 & ", ev2=" & MotionEvent2)
End Sub


Sub GD_PS_onTouch(Action As Int, X As Float, Y As Float, MotionEvent As Object) As Boolean
  Log("Posicion X: " & X & " --->>> Posicion Y: " & Y & " --->>> Accion: " & Action)
  Return GD_PS.PassTouchEventTo(MotionEvent, ScrollViewEjemplo)
End Sub
 

Informatix

Expert
Licensed User
Longtime User
Good again

I've already managed to solve re-reading all posts.

I leave it here in case it helps some other partner.

Thank you!

This is my solutions :

B4X:
.
.
.
.

ScrollViewEjemplo.Initialize2(100%y,"ScrollViewEjemplo")
MainPanel.AddView(ScrollViewEjemplo,0,0,100%x,81.8%y)
ScrollViewEjemplo.color=Colors.Transparent

paneltransparente.Initialize("")
paneltransparente.Color=Colors.argb(50,170,90,156)
paneldellamadas.AddView(paneltransparente,0,0,100%x,81.8%y)
GD_PS.SetOnGestureListener(paneltransparente, "GD_PS")

.
.
.
.
.


Sub GD_PS_onscroll(distanceX As Float, distanceY As Float, MotionEvent1 As Object, MotionEvent2 As Object)
    Log("  onScroll distanceX = " & distanceX & ", distanceY = " & distanceY & ", ev1 = " & MotionEvent1 & ", ev2=" & MotionEvent2)
End Sub


Sub GD_PS_onTouch(Action As Int, X As Float, Y As Float, MotionEvent As Object) As Boolean
  Log("Posicion X: " & X & " --->>> Posicion Y: " & Y & " --->>> Accion: " & Action)
  Return GD_PS.PassTouchEventTo(MotionEvent, ScrollViewEjemplo)
End Sub
It's one of the possible solutions indeed. Thank you for sharing.
 

andrewj

Active Member
Licensed User
Longtime User
Hi,
I'm having a couple of problems.

Firstly I'm trying to pass pinch events to a client control. I have the following code:
B4X:
Sub Gesture_onPinchClose(NewDistance As Float, PreviousDistance As Float, MotionEvent As Object)
    Log("   onPinchClose dist=" & NewDistance & ", prevdist=" & PreviousDistance & ", ev=" & MotionEvent)
    oGestures.PassTouchEventTo(MotionEvent, imgImage)
End Sub

But I get the following error:

B4X:
onPinchOpen dist=296.2574768066406, prevdist=286.24957275390625, ev=MotionEvent { action=ACTION_MOVE, id[0]=0, x[0]=306.14148, y[0]=856.45844, toolType[0]=TOOL_TYPE_FINGER, id[1]=1, x[1]=440.03955, y[1]=592.1862, toolType[1]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=2, historySize=1, eventTime=346736910, downTime=346736869, deviceId=4, source=0x1002 }
Unexpected event (missing RaiseSynchronousEvents): gesture_onpinchopen

I've tried looking at the unfiltered logs, but I can only see a dump starting with "java.lang.Throwable: stack dump" and no idea what's causing it.

Also I seem to be getting an intermittent error "Fatal signal 11 (SIGSEGV) at 0x002e0069 (code=1), thread 30516 (andrewj.stashit)". I don't know whether this is related.

Any ideas?
Thanks
Andrew
 

andrewj

Active Member
Licensed User
Longtime User
I do use the rapid debugger. However I've tried running with the legacy debugger, but that just crashes, without putting any more detailed info in the log.
Andrew
 

andrewj

Active Member
Licensed User
Longtime User
The GestureDetector_Dispatch demo works OK with Debug(Legacy). With Debug(Rapid), which is the one I usually use, it crashes and I get a similar error:

B4X:
Unexpected event (missing RaiseSynchronousEvents): gd_red_ontouch
Check the unfiltered logs for the full stack trace.
Error occurred on line: 61 (main)
java.lang.NullPointerException
    at flm.b4a.gesturedetector.GestureDetectorForB4A$1.onTouch(GestureDetectorForB4A.java:111)

Please could you find out why this isn't working with the rapid debugger?
Thanks
Andrew
 

Informatix

Expert
Licensed User
Longtime User
The GestureDetector_Dispatch demo works OK with Debug(Legacy). With Debug(Rapid), which is the one I usually use, it crashes and I get a similar error:

B4X:
Unexpected event (missing RaiseSynchronousEvents): gd_red_ontouch
Check the unfiltered logs for the full stack trace.
Error occurred on line: 61 (main)
java.lang.NullPointerException
    at flm.b4a.gesturedetector.GestureDetectorForB4A$1.onTouch(GestureDetectorForB4A.java:111)

Please could you find out why this isn't working with the rapid debugger?
Thanks
Andrew
Because I didn't make it compatible. And I'm afraid that I won't do it in a near future. However you can use the following workaround.
 

andrewj

Active Member
Licensed User
Longtime User
OK. I assume I have to add something to LibrariesExceptions.txt, but I'm still having problems. I've tried adding the following but it still doesn't work:
B4X:
1: GestureDetector.onPinchOpen
1: GestureDetector.onPinchClose

Could you please confirm what I need to be adding here?
Thanks
Andrew
 

andrewj

Active Member
Licensed User
Longtime User
Hi,

I'm afraid I also have another problem. I'm trying to handle the onFling Event, and sometimes before it gets to processing any of my code, it fails with the following error:
Fatal signal 11 (SIGSEGV) at 0x00000004 (code=1), thread 14134 (andrewj.stashit)

This is definitely in the fling handling, and happens even if I'm running release code. However if I comment out the whole onFling handler then I don't have any problem.

Any ideas?
Thanks
Andrew
 

Informatix

Expert
Licensed User
Longtime User
OK. I assume I have to add something to LibrariesExceptions.txt, but I'm still having problems. I've tried adding the following but it still doesn't work:
B4X:
1: GestureDetector.onPinchOpen
1: GestureDetector.onPinchClose

Could you please confirm what I need to be adding here?
Thanks
Andrew
Your problem is in fact with PassTouchEventTo so add GestureDetector.PassTouchEventTo to LibrariesExceptions.txt and restart B4A.
 
Top