How To Determine If A Webview Is Zoomed Out All The Way
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"