Question

By looking at other posts here I've been able to get my WebView to respond to swipes - but with some problems. What I'm trying to accomplish is make a right-to-left swipe act just like the back button in my activity. This means sometimes calling webview.goBack or LoadURL to go to a previous page, or if I'm at the top webpage calling super.onBackPressed to close the current webview.

The latter case works perfectly, but the browser controls are only partially working. If I open the webview and go two pages deep, then swipe back once, I see no change. If I swipe back again, the webview gets closed. This means the previous webpage was loaded on the first back swipe, but it wasn't displayed on the screen for some reason. If I use the device's back button (which calls exactly the same function as my onFling), the display refreshes as expected. Does anyone know what could be causing this behavior? Does it have something to do with the webview motion events overriding an action somewhere?

The relevant pieces of code are below. Thanks for taking a look.

public class WebBrowser extends Activity ... {

    ...

GestureDetector gestureDetector;

SimpleOnGestureListener gestureListener = new SimpleOnGestureListener() {

    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if (Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY && Math.abs(e2.getX() - e1.getX()) > SWIPE_MIN_DISTANCE) {
            goBack();
            return true;
        }
        return false;
    }
};

public void onCreate(Bundle savedInstanceState) {
        ...
    gestureDetector = new GestureDetector(gestureListener);
    wv.setOnTouchListener(
            new View.OnTouchListener() {
                public boolean onTouch(View wv, MotionEvent event) {
                if(gestureDetector.onTouchEvent(event)) return true;
                return false;
            }
    }
    );

private void goBack() {
    if (backURL.equals("close")) {
        super.onBackPressed();
    } else if (!backURL.equals("")) {
        wv.loadUrl(backURL);
    } else if (wv.canGoBack()) {
        wv.goBack();
    } else {
        super.onBackPressed();
    }
}

}

Was it helpful?

Solution

I had the same problem. Try:

public void onCreate(Bundle savedInstanceState) {
    ...
gestureDetector = new GestureDetector(gestureListener);
wv.setOnTouchListener(
        new View.OnTouchListener() {
            public boolean onTouch(View wv, MotionEvent event) {
                gestureDetector.onTouchEvent(event);
                return false;
            }
        }
);

So return always false, although the detector returned true. I know it's not the way it is supposed to be, but it worked for me.

OTHER TIPS

Alf is on the right track. The "setOnTouchListener" needs to be added to the webview, but the kludge on gestureDector is not needed. Here is the complete solution...

    // LOAD WEBVIEW WITH HTML
    wv.loadDataWithBaseURL(null, htmlSource, "text/html", "utf-8", null);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    // GESTURE DETECTOR: FLINGLEFT
    gestureDetector = new GestureDetector(this,
            new GestureDetector.SimpleOnGestureListener() 
    {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
        {
            if (e1.getX() - e2.getX() > LARGE_MOVE)
            {
                setResult(Activity.RESULT_OK, new Intent().putExtra("GESTURE", "FLINGLEFT"));
                finish();
            }
            return false;
        }
    });

    // SET ON TOUCH LISTENER
    wv.setOnTouchListener(
            new View.OnTouchListener() {
                public boolean onTouch(View wv, MotionEvent event) {
                    gestureDetector.onTouchEvent(event);
                    return false;
                }
            }
    );

This can be extended with other flings and other motion events.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top