How to disable doubletap zoom in android webview?

2019-01-26 00:28发布

问题:

How to disable the doubletap zoom in android webview. I have tried many things but it haven't worked. Please suggest me the right solution to achieve this .

Actually I am loading an image from custom html . I have to disable complete zooming for that.

I have tried the below things,

webview.getSettings().setSupportZoom(false);

and even I kept meta tag in html and I make it as userscalable= no. Even it doesn't worked for me.

And I tried using GestureDetector.SimpleOnGestureListener

Please let me know that i have to scale anything in onDoubleTap.

回答1:

Override the onTouchEvent in your WebView.
It works in all cases.

@Override
public boolean onTouchEvent( MotionEvent event ) {

    if (event.getAction() == MotionEvent.ACTION_UP) {

        event.setAction(MotionEvent.ACTION_CANCEL);
        super.onTouchEvent(event);
        event.setAction(MotionEvent.ACTION_DOWN);
        super.onTouchEvent(event);
        event.setAction(MotionEvent.ACTION_UP);
    }

return super.onTouchEvent(event);
}


回答2:

Did you check the question below? Please check, this may be related with your question.

Android WebView use setWideViewPort, disable double-tap zoom but keep pinch zoom?



回答3:

After lots of trial and error and research on SO, I come up with the following solution that works for my app.

public class HelpWebView extends WebView {

    private GestureDetector gestureDetector;
    private AtomicBoolean mPreventAction = new AtomicBoolean(false);

    public HelpWebView(Context context) {
       super(context);
       gestureDetector = new GestureDetector(context, new GestureListener());
    }

    public HelpWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        gestureDetector = new GestureDetector(context, new GestureListener());
    }

    public HelpWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        gestureDetector = new GestureDetector(context, new GestureListener());
    }

    public HelpWebView(Context context, AttributeSet attrs, int defStyle, boolean     privateBrowsing) {
        super(context, attrs, defStyle, privateBrowsing);
        gestureDetector = new GestureDetector(context, new GestureListener());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int index = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>     MotionEvent.ACTION_POINTER_INDEX_SHIFT;
        int pointId = event.getPointerId(index);

        // just use one (first) finger, prevent double tap with two and more fingers
        if (pointId == 0){
            gestureDetector.onTouchEvent(event);

            if (mPreventAction.get()){
                mPreventAction.set(false);
                return true;
            }

            return super.onTouchEvent(event);
        } else {
            return true;
        }
    }

    private class GestureListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            mPreventAction.set(true);
            return true;
        }
        @Override
        public boolean onDoubleTapEvent(MotionEvent e) {
            mPreventAction.set(true);
            return true;
        }
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            // onSingleTapConfirmed will only be called after the detector is confident
            // that the user's first tap is not followed by a second tap leading to a double-tap gesture
            return false; // it doesn't matter for the return value here as we only check mPreventAction above
        }
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            mPreventAction.set(true); // this is the key! this would block double tap to zoom to fire
            return false;
        }
    }
}

I took reference from the following SO answers: https://stackoverflow.com/a/14724407/510577 https://stackoverflow.com/a/15547887/510577



回答4:

After a lot of research, I merged some answers that did not worked separately, and realised that together worked perfectly for me.

This disables double tap zoom in a WebView.

First, you need to set this in your WebView:

YourWebView.getSettings().setUseWideViewPort(false);

Then, you need to scale your WebView. But first need to get the scale value:

private int GetWebViewScale(){
    int WebViewWidth = YourWebView.getWidth();
    Double WebViewScale = new Double(WebViewWidth)/new Double(YourWebWidth); //Here, you must change YourWebWidth with your web width (in pixels)
    WebViewScale = WebViewScale * 100d;
    return WebViewScale.intValue();
}

Now you can get the scale value with:

YourWebView.setInitialScale(GetWebViewScale());

But, it will not work if you start the code too early, so you will put that code in WebViewClient's onLayoutChange override like this:

YourWebView.addOnLayoutChangeListener(new View.OnLayoutChangeListener(){
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        YourWebView.setInitialScale(getScale());
    }
});

Attention: You will probably have thess issues: (Both happened to me)

  • The WebView moves a little bit horizontally. (#1)
  • The WebView is not scaling. (#2)

Fix issue #1:

  • Just add some pixels in the "YourWebWidth" value. For example:

Before:

Double WebViewScale = new Double(WebViewWidth)/new Double(500); //(500 is my web's width)

After:

Double WebViewScale = new Double(WebViewWidth)/new Double(505); //(500+5) - (This will add some padding at the left and right of your WebView. 2,5px at the left side; 2,5 at the right side)

Fix issue #2

  • Probably your WebView's visibility is "gone", and when it is, it does not have width. So calling "GetWebViewScale" will not work.

  • You need to call it when its visibility is "visible" or "invisible".