Skip to content Skip to sidebar Skip to footer

How To Determine If A Webview Is Zoomed Out All The Way

I'm looking for a way to detect whether or not a WebView is zoomed out fully. I know you can get a boolean return value from ZoomOut(), but that will perform the zoom out. I just

Solution 1:

I use my custom WebView class.

Get WebView's view height and inner html web page's contentHeight.

Calculate defaultScale = WebView.getHeight() / WebView.getContentHeight(); and currentScale = WebView.getScale().

If defaultScale < currentScale it's zoomed.

publicclassNoZoomControllWebViewextendsWebView {

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)@SuppressWarnings("deprecation")publicbooleanisZoomed() {
        booleanresult=false;

        intcontentHeight= getContentHeight();
        intviewHeight= getHeight();

        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR1 ) {
            floatscale= getScale();
            inttemp= (int)(((float)viewHeight / (float)contentHeight) * 100);

            if (temp < (int)(scale * 100)) {
                result = true;
            }
        } else {
            floatscale= getScale();
            inttemp= (int)(((float)viewHeight / (float)contentHeight) * 100);

            if (temp < (int)(scale * 100)) {
                result = true;
            }
        }

        return result;
    }
}

Solution 2:

getScaled() is deprecated you should use onScaleChanged on your WebViewClient instead

You can use it like this:

privatebooleanzoomed=false, firstRun = true;

            @OverridepublicvoidonScaleChanged(WebView view, float oldScale,
                    float newScale) {
                if (firstRun) {
                    initScale = newScale;
                    firstRun=false;
                    zoomed = false;
                }
                else {
                    if (newScale>oldScale) {
                        zoomed = true;
                    }
                    else {
                        if (newScale<initScale) {
                            zoomed = false;
                        }
                    }
                }
                super.onScaleChanged(view, oldScale, newScale);
            }

if we presume the WebView is zoomed max out from the start.

Solution 3:

Create your own class which extends WebView and override the zoomOut() method. Every time the user zooms out, call super.zoomOut(). Save what is returned to a boolean variable with class scope so it can be persisted with onSaveInstanceState() or in SharedPreferences if needed.

publicclassMyWebViewextendsWebView {

    // WebViews are generally zoomed out all the way when first created so set defaultsprivateboolean lastZoomInResult = true;
    privateboolean lastZoomOutResult = false;

    @OverridepublicbooleanzoomIn() {
        lastZoomInResult = super.zoomIn();
        return lastZoomInResult;
    }

    @OverridepublicbooleanzoomOut() {
        lastZoomOutResult = super.zoomOut();
        return lastZoomOutResult;
    }

EDIT: In response to this not working for pinch zoom... you are quite correct and ultimately Cristian's answer holds true.

I hooked my phone up via USB to my PC with DDMS. I see the following when I pinch zoom my Webview...

01-0603:18:19.052: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x849ac0), pid=23072, w=1, h=101-0603:18:19.052: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x849ac0), pid=23072, w=1, h=101-0603:18:19.082: DEBUG/SurfaceFlinger(92): Layer::requestBuffer(this=0x849ac0), index=0, pid=23072, w=480, h=74 success
01-0603:18:19.832: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x738378), pid=23072, w=1, h=101-0603:18:19.832: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x738378), pid=23072, w=1, h=101-0603:18:19.852: DEBUG/SurfaceFlinger(92): Layer::requestBuffer(this=0x738378), index=0, pid=23072, w=480, h=74 success

In short, it isn't WebView which is zooming. What's actually happening is a digital zoom of the graphics display - the WebView content stays exactly the same size regardless of a zoom in or out but it's being digitally 'magnified' or 'shrunk' like the digital zoom on a digital camera.

I don't fully understand what SurfaceFlinger is but from a quick Google search, we're talking 'device driver' stuff here.

The only thing that changes in those SurfaceFlinger log messages are the hex value for 'this=' and they bear no relevance to the zoom state. The above is logging two pinch attempts when the screen was fully zoomed out.

Solution 4:

I'm curious to see what else anyone might come up with but I was able to accomplish this through javascript. It's frustrating because I can see the values needed to easily determine this in the source code of the WebView but they are private with no getters...

Anyhow the solution I have so far is add a JavaScriptInterface which allows me to get the document.body.scrollWidth value for the page. This provides me with the scrollable width, which for some reason is not available even though there is a getContentHeight() method. Using this, I can calculate whether or not it is fully zoomed out.

Here is the method the javascript interface calls:

publicvoidcheckIfZoomedOut(int scrollWidth){
   int zoomedOutThreshold = 5; // If you want to include "nearly zoomed out"if( Math.abs(Math.ceil(mWebView.getScale() * scrollWidth) - mWebView.getWidth()) <= zoomedOutThreshold){
       // It is zoomed out
   } else {
       // It is zoomed in
   }

}

The scrollWidth is document.body.scrollWidth

Edit: After further experimenting I found protected methods called computeHorizontalScrollRange() and computeHorizontalScrollExtent() that can be called if you subclass the WebView. You can use them to determine if horizontal scrolling is active/needed. However, some webpages can be fully zoomed out (the WebView won't let you zoom out any further) and still have a horizontal scrollbar, such as webpages with text. So it's not perfect.

Solution 5:

if( !webView.zoomOut () ){
   // couldn't zoom out because the zoom out did nothing :(// THIS IS WHAT YOU WANT TO KNOW!
} else{
    webView.zoomIn(); // restore
}

I just want to simply know whether or not it can.

There's no way to do so.

Post a Comment for "How To Determine If A Webview Is Zoomed Out All The Way"