A specific method needs to be called whenever a gesture ends. Currently, I'm using an if statement to see if a MotionEvent is ACTION_UP to do this. However, I've discovered that if I lift my finger while swiping quickly, the MotionEvent is not an ACTION_UP, but an ACTION_MOVE. It only works properly if I lift while the finger is not moving.
Any suggestions or alternative solutions?
Thanks in advance.
EDIT: problem solved
Well, I figured out what was wrong. I was using some booleans to prevent ConcurrentModificationExceptions when onTouchEvent modifies a list of objects that my renderer was also drawing. Turns out that this was ending the method early half the time. I ended up synchronizing the lists, and now it works fine.
Related
I am a newbie in Android, lately I got this weird thing:
I have my customized View, in onTouchEvent method, i tried to detect multitouch gesture, but the MotionEvent.ACTION_POINTER_DOWN will always be triggered no matter my second finger touches the view or not.
It seems like ACTION_POINTER_DOWN doesn't behaves the same as ACTION_DOWN, since ACTION_DOWN will not be triggered if my finger didn't touch the view.
Please tell me what's wrong with that, is that a bug?
Its working as intended. Once you touch down, all touch events go to your view until a cancel or an up occurs.
I have implemented custom view with some children. The view can be scrolled using standard drag gesture. Also every child can be clicked. The problem is, that when I start dragging the view, one of children gets 'down' event and it changes its state to 'pressed' for a second. I would prefer standard listview behavior - the child goes into pressed state when the user keeps pressing this child with his/her finger for like 50ms. It would reduce blinking caused by misread press event.
I know, that I need at least 2 events to detect if the user is tapping or dragging the view. For now I'm using TimerTask to shedule 'down' event. When I get 'move' event before my 'down' event is executed, I know that the user is dragging and I can cancel the sheduled event.
I know it's quite hacky. I also tried gesturedetector to detect drag and tap events, but it needs some additional work to properly implement changing view state from pressed to default when the user moves finger and starts to drag the view.
My question is - how this is implemented in android listview? I tried to copy their solution from listview implementation, but it's so huge I can't handle it. Simply I don't see the code responsible for handling such situation.
I managed to understand a gesture detection logic in ListView and, in general, in android views. I wrote my own gesture detector, which is somewhat better than the original one. It reports more gestures (multiple taps, dragging) and has some configurables (timeouts, move epsilon). You can find it open-sourced here: Better Gesture Detector on code.google
The library uses Handler class and postDelayed()/removeCallbacks() method combination to detect, handle and cancel motion events and gestures. It's quite simple and one should be able to get the idea by just reading the code.
This repository also contains a simple demo. Please note that this code is provided 'as is', contains some useless comments, logs and should be cleaned up a bit.
In case my title wasn't clear enough, I'll explain it in detail:
Say we have a screen filled with multiple buttons (10+), and we press down on one, activating onTouch/onClick. If we now move the finger, without lifting it, I want it to activate any other button it slides over. In this particular case, I want sound to be played when you slide over a virtual piano.
I know about the onTouchListener-solution where you register every ACTION_MOVE and find some boundaries that activates new events, but that's far from optimal if you have multiple buttons and want to allow smooth sliding without delay.
I also read this thread which suggested that we combine the touchListener of the View with a gesturelistener from the activity, but once again, this does not feel at all optimal for my situation.
I have not tried combining touchlistener with gesturelistener yet, but I will go ahead and do so if someone tells me they have no other way of doing this.
In my opinion, the proper way of doing this is to forget about buttons, and create a custom view which draws the entire keyboard. In this view you can handle touch events the way you like. You do not even need the gesture detector, just analyze the action and coordinates of motion events, it's very easy.
I don't understand what you mean about ACTION_MOVE and delays. To minimize delay, react on ACTION_DOWN, and then on ACTION_MOVE if it hovers other keys while in down state. It can't be any faster than that. With buttons there is an important delay because the onClick() event is triggered when the user lift the finger, on ACTION_UP.
Buttons are just not meant to work as you describe. The idea is that if a user taps on a button and then move his finger away at the same time it does not trigger onClick events on other views around. This prevents bogus clicks.
I actually took the "easy" way out and used buttons with an onTouch-method using ACTION_DOWN and ACTION_MOVE with coordinate calculations that combined with event.getX() and event.getY() allows me to detect which button is currently hovered. It's lag free with 13 buttons.
I have a scrollview in my layout and I want to be able to check if the user is scrolling. I checked the Scrollview in Android Docs, but I don't see anything like isScrolling() that returns a boolean.
My question is: is there a way to check if the user is attempting to scroll, as opposed to clicking a button? Could there be some other class in the Android core that is monitoring the scroll event?
There could be a better way but here is how you can figure it out.
You get a MotionEvent object inside the onTouchEvent(MotionEvent ev) method.
check the action of the motion event as ev.getAction().
If the action is ACTION_MOVE it implies that a scrolling is taking place.
Note: Scrolling is different than a fling. So the same logic cannot be used to determine if the fling is over.
I have been new to android. I have just gone through my slideshow app.
I want to make image slide using touch event just like facebook app. when we click on image and swipe it to left then new image shown and when swipe finger towards right then last old image is shown.
I don't know how this works and how to start with it. Can any one help me in this case to start with like providing tutorials and tips ?
I just want effect on the image.
Handling simple touch events works the following:
You need an OnTouchListener in your Activity. Add it by implementing the OnTouchListener interface.
You will have to override the onTouch(View v, MotionEvent event) method. This will be called if a touch gesture is recognized.
Now you get all the information about the Touch (in Android it is called MotionEvent) in the onTouch Method via the MotionEvent. Look at the MotionEvent-Class documentation to use the correct methods to handle your swipe gesture.
You could first ask what action really happened. Call getAction(). It will return the type of action. The easiest way would be to react to ACTION_MOVE.
Then ask for the origin of the touch event and the later position of the touch by using getHistoricalX(int)/getHistoricalY(int) and getX(int) and getY(int) (attention: these methods are only usable for ACTION_MOVE events - in your case it is ok).
Now as you have the start and end coords of the swipe gesture, you can calculate the length of the swipe in pixels and the direction of the swipe and that is all what you need.
Good Luck!
There's two bits of information that you might want. The first thing is, what you are referring to is called a gallery. There's several great examples of how to use a gallery, the basic idea is you get a BaseAdapter Class that gets the view and attach it to the gallery. See this tutorial for an example, or just google Android Gallery Example, you'll find alot of examples.
The second is gesture programming. Take a look at this tutorial for more information