Initiate zoom within an Android WebView from a longpress - android

I am looking for a way to replicate the native WebView zoom on double-tap but triggered via a long press instead. As, with the double-tab zoom I'd like the zoom to scale centered around the point of touch and then be able to scale back out to the default zoom level programmatically.
I was thinking there might be a way to spoof the double-tap gesture to the WebView within the longpress handler and provide it the coordinates of the long press but I am unable to find a way to do it.
Can this be done?

Found a workable if a bit of a hacky solution to this based upon information found in this post:
Double tap Programmatically on WebView
I replaced the content of:
public void simulateDoubleTap()
{
simulateDoubleTapEvent(0);
simulateDoubleTapEvent(2);
simulateDoubleTapEvent(2);
simulateDoubleTapEvent(1);
simulateDoubleTapEvent(0);
}
With:
public void simulateDoubleTap()
{
simulateDoubleTapEvent(MotionEvent.ACTION_DOWN);
simulateDoubleTapEvent(MotionEvent.ACTION_UP);
simulateDoubleTapEvent(MotionEvent.ACTION_DOWN);
simulateDoubleTapEvent(MotionEvent.ACTION_UP);
}
And then added a call to simulateDoubleTap() from within my longpress handler. This seemed to work - but it was not 100% consistent. May want to play with adding some small delays between the events and see if that smooths it out. Also I noticed that when zooming in, things would work with a single event, but it was taking two triggers of the double-tap to zoom back out. This may be because of the gesture handler I am using, or some other issue, but generally this seems to do what I need.

Related

onTap is recognized as onPanStart MapGesture

Sometimes when i tap on the map the tap is recognized as onPanStart. I need to do something when the user swipes on the map and something different when he taps , but there is no onSwipe gesture in the MapGesture.OnGestureListener. With using onPanStart sometimes the wrong action is called. Is there a better way to handle this?
Differentiating between gestures is somewhat subjective and as a result the parameters are generally tweaked to provide a good UX for the given use case.
Without knowing more about your exact use case, if you want the actions to correspond directly to how the HERE SDK is interpreting the input, then using the callbacks onPanStart and onTapEvent would be the right thing to do. Note that even though a Pan is technically triggered, it could have such a small velocity that the Map doesn't move much. "Pan" is equivalent to a "Swipe" gesture.
If you do want to tweak the UX a bit, an option would be to write your own Android GestureDetector to get the feel you would like (potentially fusing the result with the output of OnGestureListener events as well). Alternatively, you could also check that the Map actually moves a certain amount after onPanStart is called before triggering your event, perhaps using Map#OnTransformListener but this could be tricky to get right.

What's the proper interaction between ScaleGestureDetector's new "quick scale" feature and a GestureListener's onDoubleTap()?

The KitKat SDK supports a new type of scale gesture called quick scale. Instead of requiring two fingers to pinch zoom, the user can doubletap and swipe to scale a view. You can see this in action in the Chrome and Maps apps.
Both Chrome and Maps differentiate between a doubletap (which zooms into the relevant content area, as before) and a doubletap-swipe (which allows you to scale arbitrarily with one finger).
Under the hood, the ScaleGestureDetector uses a GestureDetector to detect doubletaps and start looking for the corresponding swipe.
My question is how to mimic Chrome and Maps, detecting both doubletaps and this doubletap-swipe gesture but not both at the same time. That is, I'd like to differentiate between a normal doubletap (no swipe) and a doubletap-swipe.
I have both a GestureDetector and a ScaleGestureDetector being fed all touch events on my view. Currently, both GestureListener.onDoubleTap() and ScaleGestureListener.onScaleBegin() fire when I do a doubletap-swipe. onDoubleTap() gets fired first, so there's no way cancel handling events in the ScaleGestureListener.
I see two possible solutions, neither of which is very clean:
Copy the ScaleGestureDetector from the Android source and add a new callback to the ScaleGestureListener interface for something like onDoubleTapConfirmed() (doubletap, no swipe).
Add a small delay to onDoubleTap() so we handle the event X milliseconds after it gets triggered. If onScaleBegin() gets fired before the delay is up, cancel handling the onDoubleTap() event and start handling the scale instead.
What's the best way to handle this?
A bit late to this party, but the quick scale is more like an unfinished double tap on which the second tap turns into a drag, something like:
tap down, tap up, tap down, move
It seems your interpretation of quick scale is:
tap down, tap up, tap down, tap up, tap down, move
Which makes your problem a lot easier if you only register a plain double tap on the second action down. When the second action up happens, you just need to figure out whether a drag has happened during the second tap cycle. In case the gesture recognizers don't work for you, you can do that manually by checking against getScaledTouchSlop.
Also, copying the ScaleGestureDetector is probably not as bad as you think - github is littered with "compat" projects that are basically backports of features in newer SDK versions.

Android: OnTouch event features, detecting a normal touch, a long touch or a quick double touch

I need to know how i can make my activity to know when a user touches the screen, double touches it, or holding the finger on it for a long touch on a single view, with out using buttons
Could some one briefly describe me witnh what i should work here, and what logic to use?
You need to have some View or layout item that encompasses the screen, so that all the touch events are sent to it. From there, you need to attach a listener of some kind (touch or gesture, probably).
I would recommend either a GestureDetector (this supports double tapping and other gestures), or a basic touch listener (uses MotionEvent, which doesn't have double tap, but you could implement this yourself).
If you use MotionEvent, you can detect how long the finger has been down with getDownTime(). For a double tap, you can record the time of the last press (using Calendar or similar), then check if the last press was within some amount of time (maybe 500ms?).
If you use GestureDetector, you can implement these differently. Take a look at this answer for more details (other answers in that thread provide alternatives as well). It also supports MotionEvent objects, so that shouldn't be a problem.

Reconciling scroll, fling, tap, zoom and pan on the same view in Android

I am working on an application that can read pdf documents and I am trying to implement zooming and panning on a pdf page.
The page is loaded as a bitmap and displayed in an ImageView. There are also some other functionalities already implemented such as navigating the pages in a document with a bottom custom navigation bar that can be scrolled.
Also, the bottom bar appears when the user taps on the page and disappears with the next tap and when flinging, users should be able to navigate to next/previous page in the document.
All functionality such as the scroll, tap and fling is handled by implementing OnGestureListener in the reader activity and I am trying to do the zoom and pan with an OnTouchListener implementation that is set on the ImageView containing the page.
The code seems to work, however it appears that some of the other events, especially the scroll, are interfering with it which makes it slow.
My question is if there is a better way to go about reconciling everything, since the OnGestureListener is used for the GestureDetector's handling of onFling, onTapUp and onScroll, but I can't find a good way to add the zoom/pan code in one of the methods supported by this.
So, if anyone has some experience on handling all these events for one view or some good suggestions/tutorials on this, I would very much appreciate it.
I'm not sure what you mean by 'some other events such as the scroll make it slow', could you elaborate?
You should be able to perform zoom and pan using onTouch fairly trivially, without scrolling being an issue if you choose to use Canvas. Full implementation code can be found at Touch and drag image in android for scrolling, and http://www.zdnet.com/blog/burnette/how-to-use-multi-touch-in-android-2-part-6-implementing-the-pinch-zoom-gesture/1847 for zooming.
It's generally not common to see advanced interactive features applied solely on an ImageView, but that doesn't mean people haven't done it (see How can I get zoom functionality for images? for zoom examples including support for multi-touch or Adding Fling Gesture to an image view - Android ).
Regardless of which way you do it, you'll probably want a GestureDetector in your onTouch function. You should be able to just cut and splice together sections of the tutorials I've linked to in order to get full gesture support + zoom/pan. However, if I were doing it, I would probably just use onTouch with Canvas (since Canvas will give better performance) and use the core MotionEvents such as DOWN MOVE UP for greater control, or if I was feeling lazy, use a GestureDetector for trickier bits like flinging.

Android - Detect Path of Complex Drag

I am recently getting into Android programming and want to make a simple game using 2D canvas drawing. I have checked out the Lunar Lander example and read up on some gestures, but it looks like I can only detect if a gesture occurred. I am looking to do a little more complicated detection on a swipe:
I want to make a simple game where a user can drag their finger through one or more objects on the screen and I want to be able to detect the objects that they went over in their path. They may start going vertically, then horizontally, then vertically again, such that at the end of a contiguous swipe they have selected 4 elements.
1) Are there APIs that expose the functionality of getting the full path of a swipe like this?
2) Since I am drawing on a Canvas, I don't think I will be able to access things like "onMouseOver" for the items in my game. I will have to instead detect if the swipe was within the bounding box of my sprites. Am I thinking about this correctly?
If I have overlooked an obvious post, I apologize. Thank you in advance!
I decided to implement the
public boolean onTouchEvent(MotionEvent event)
handler in my code for my game. Instead of getting the full path, I do a check to see which tile the user is over each time the onTouchEvent fires. I previously thought this event fired only once on the first touch, but it fires as long as you are moving along the surface of the screen, even if you haven't retouched.

Categories

Resources