Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override some gesture events over a webview, but let others through?

I'm still figuring out the ins and outs of the SDK so bear with me here.

So i'm trying to implement a Webview, that keeps multitouch zoom controls and vertical scroll intact (webview class handles them) while locking horizontal scroll on the Webview, and implementing horizontal flings to seek new data.

I found this: Fling Gesture and Webview in Android . I therefore took this code to understand how to implement this in my app later, so I'm working from there (the answer, of course).

And started modyfing the code to my suiting. For example:

   if (event1.getRawX() > event2.getRawX() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100) {
    show_toast("swipe left");
   } else if(event1.getRawX() < event2.getRawX() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100){
    show_toast("swipe right");

Actually detects ONLY horizontal flings.

However, I have not figured out how to make sure that horizontal flings trigger an action of my choosing, while vertical flings still control the scroll of the WebView in question.

My first thought was to try something like pageUp/pageDown or scrollTo on the webview but that can't work since i'm extending the webview class to MyWebView and therefore don't yet have an instanciated object of this type.

This is the full code, if needed:

package test.fling;


import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.webkit.WebView;
import android.widget.Toast;

public class testicules extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    MyWebView webview = new MyWebView(this);
    webview.loadUrl("http://en.wikipedia.org/wiki/Android");
    setContentView(webview);
}

class MyWebView extends WebView {
 Context context;
 GestureDetector gd;

public MyWebView(Context context) {
super(context);

this.context = context;
     gd = new GestureDetector(context, sogl);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
return gd.onTouchEvent(event);
}

 GestureDetector.SimpleOnGestureListener sogl = new GestureDetector.SimpleOnGestureListener() {
  public boolean onDown(MotionEvent event) {
   return true;
  }
  public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
   if (event1.getRawX() > event2.getRawX() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100) {
    show_toast("swipe left");
   } else if(event1.getRawX() < event2.getRawX() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100){
    show_toast("swipe right");
   } else {
     //MyWebView.pageUp(true); /*can't work, as explained above*/
   }
return true;
  }
 };

 void show_toast(final String text) {
  Toast t = Toast.makeText(context, text, Toast.LENGTH_SHORT);
  t.show();
 }
}
}

Any Help would be greatly appreciated. Thanks!

like image 253
Robin Eisenberg Avatar asked Feb 25 '23 22:02

Robin Eisenberg


1 Answers

What you want to do here is add code to your onTouchEvent to check the return value from the GestureDetector's onTouchEvent, and if it is false, then call the WebView superclass with the event, like this:

<code>
    @Override 

    public boolean onTouchEvent(MotionEvent event) {

        return (gd.onTouchEvent(event) 
            || super.onTouchEvent(event)); 
    }  
</code>

Then, your onFling method can return true if you're handling the event, or false if you want the WebView to handle the event. You also need to change onDown to return false, so the WebView gets a chance at the initial down event.

like image 101
Roger Powell Avatar answered Apr 06 '23 23:04

Roger Powell