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,007
  • Java source - GestureDetector.zip
    5.5 KB · Views: 1,150
Last edited:

TheMightySwe

Active Member
Licensed User
Longtime User
But i can invent some other way to rotate them if its not possible to use onRotate in that way. No problem.
 

Informatix

Expert
Licensed User
Longtime User
But i can invent some other way to rotate them if its not possible to use onRotate in that way. No problem.
I understood where's your mistake. You bound the GD to the view that you want to rotate. For two-fingers actions, the GD has to be bound to the container holding the view (a panel, the activity, etc.) not to the view itself. Look at my code. The GD is bound to the activity containing the panel, not to the panel to rotate.
 

TheMightySwe

Active Member
Licensed User
Longtime User
I understood where's your mistake. You bound the GD to the view that you want to rotate. For two-fingers actions, the GD has to be bound to the container holding the view (a panel, the activity, etc.) not to the view itself. Look at my code. The GD is bound to the activity containing the panel, not to the panel to rotate.


OK, so I can basiclly not get the Button from the Sender then, so I have to invent another way to rotate the button.

Because I already use a lot of the other events and they work like clockwork except onPinch and the other two finger gesture, but that has to be for the same reason.

I think i will use Doubleclick to clear the panel from all other Buttons except the one i doubleclick, set the GD to the ScrollPanel2D and see what happens. Then use doubleclick again to save placement, angle and the rest and reload from database.
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
OK, so I can basiclly not get the Button from the Sender then, so I have to invent another way to rotate the button.
When you rotate a button, unless it is quite big, your fingers are not on the button, so how do you know the view to rotate? If you can answer to this question, then you can use GD to rotate the view. Usually the trick is to put each view to rotate in a bigger but invisible container. Another idea is to rotate the button touched by one of the fingers (but nothing will happen if the two fingers are outside the button area).
 

TheMightySwe

Active Member
Licensed User
Longtime User
Hi,

Thanks for the help, i found a way to fix the problem. I did like this, in the administration mode I use "onSingleTapConfirmed" to set the button to a Dummy ButtonView in Globals

When I use a GD that is linked to the panel on the two finger gestures. It works like a charm.

I removed the onRotate to the GD that handles the single button.

I don't know if it's the best looking solution, but it works. Thats the most important thing.

Now I have to work out how to limit the buttons size and snap them to a invisible grid.

Thanks for helping me again.

B4X:
Sub ButtonAdminGesture_onSingleTapConfirmed(X As Float, Y As Float, MotionEvent As Object)

    If Debug Then Log("ButtonAdminGesture_onSingleTapUp(MotionEvent=" & MotionEvent & ")")
    ClickedButton = Sender ' Dummy in Globals

End Sub
 

TheMightySwe

Active Member
Licensed User
Longtime User
Hi, sorry to pest you with more questions.

Is it possible to "drag and drop" a button from one panel to another?

What events shall I use in that case if its possible?
 

Bill Kantz

Member
Licensed User
Longtime User
I am getting an error when trying to used GD with Margret's Toast Msg Class. I assume it is some conflict over touch events. It is triggered when I use a fling. This happen even after I dismiss the Toast msg with a tap.

both GD and reflection up to date.

Thanks
Bill


B4X:
** Service (ws) Start **
java.lang.NullPointerException
    at android.view.GestureDetector.onTouchEvent(GestureDetector.java:587)
    at flm.b4a.gesturedetector.GestureDetectorForB4A$1.onTouch(GestureDetectorForB4A.java:119)
    at android.view.View.dispatchTouchEvent(View.java:5544)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1951)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1712)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1912)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1371)
    at android.app.Activity.dispatchTouchEvent(Activity.java:2364)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1860)
    at android.view.View.dispatchPointerEvent(View.java:5729)
    at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2960)
    at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2469)
    at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:845)
    at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2478)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4456)
    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:787)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
    at dalvik.system.NativeStart.main(Native Method)
 

Informatix

Expert
Licensed User
Longtime User
I am getting an error when trying to used GD with Margret's Toast Msg Class. I assume it is some conflict over touch events. It is triggered when I use a fling. This happen even after I dismiss the Toast msg with a tap.

both GD and reflection up to date.

Thanks
Bill


B4X:
** Service (ws) Start **
java.lang.NullPointerException
    at android.view.GestureDetector.onTouchEvent(GestureDetector.java:587)
    at flm.b4a.gesturedetector.GestureDetectorForB4A$1.onTouch(GestureDetectorForB4A.java:119)
    at android.view.View.dispatchTouchEvent(View.java:5544)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1951)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1712)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1912)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1371)
    at android.app.Activity.dispatchTouchEvent(Activity.java:2364)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1860)
    at android.view.View.dispatchPointerEvent(View.java:5729)
    at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2960)
    at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2469)
    at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:845)
    at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2478)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4456)
    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:787)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
    at dalvik.system.NativeStart.main(Native Method)
You should see that with Margret because I don't know at all her class/library. I cannot do anything for you on the GD side.
 

thehe

Member
Licensed User
Longtime User
I change GestureDetector_Drag for a kinder dragging game

Moving pnlGreen to Globals section

In Activity_Create, the bacground is set to PictureA

' pnlGreen.SetBackgroundImage(LoadBitmap(File.DirAssets,"PictureA.png"))

In Gesture_onTouch function

If action = 1 ' (Mouse-UP, drop)

' incompare to some matching position

' the HIT and INVISIBLED test is working

'but the SWAP picture NEVER change.

'How I can REFRESH or Invalidate to show new picture

the bacground picture is set to PictureB

pnlGreen.SetBackgroundImage(LoadBitmap(File.DirAssets,"PictureB.png"))

Above code do not show picture B
 

mtechteam

Member
Licensed User
Longtime User
I am new to b4a but have a working app for our company. I have not worked on getting Gestures or Gesture_Detector working yet, would it take care of the issue of swiping over a label? We used a label on the activity to display text from a file. Swipe works on the edge (outside the label area) but not over the top of the label (text) itself.

Thanks, Tim
 
Top