How to Set the Initial Zoom/Width for a Webview

How to set the initial zoom/width for a webview

The following code loads the desktop version of the Google homepage fully zoomed out to fit within the webview for me in Android 2.2 on an 854x480 pixel screen. When I reorient the device and it reloads in portrait or landscape, the page width fits entirely within the view each time.

BrowserLayout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<WebView android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>

Browser.java:

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;

public class Browser extends Activity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.BrowserLayout);

String loadUrl = "http://www.google.com/webhp?hl=en&output=html";

// initialize the browser object
WebView browser = (WebView) findViewById(R.id.webview);

browser.getSettings().setLoadWithOverviewMode(true);
browser.getSettings().setUseWideViewPort(true);

try {
// load the url
browser.loadUrl(loadUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
}

Set WebView initial zoom level (start it so page fits)

scalesPageToFit avoids your web page to outscale in the webView, so that its minimum zoom does not show empty spaces.
Since React Native Docs version 0.52 a new prop initialScale is provided and seems to be exactly what you're looking for. Unfortunately it has never been added to the code: an issue is still open.

So, in order to achieve your objective, you have to use nativeConfig to override the native component behavior: what I mean is fully explained in these two examples:

  1. First
  2. Second

Android Webview initial zoom out

webview.getSettings().setLoadWithOverviewMode(true);    

This will cause the webview to be zoomed out initially.

webview.getSettings().setUseWideViewPort(true);

The Webview will have a normal viewport (like desktop browser), when false the webview will have a viewport constrained to it's own dimensions.

EDIT: With the introduction of "Chrome web view" in Android KitKat, this code might not work.

Set minimum zoom level of webview (Android)

I think I found a solution for most situations like this, as long as we just want to load a single image. It's kind of a workaround, and loses some image details as it resizes the image. Nevertheless it should work on most if not all devices out there.

I followed the approach to embed the image into a basic HTML page, and filled the <img> tag with the width of the screen in pixels. For simplicity I skipped loading the HTML from a file and just generated it inside my Java code:

private String generatePage() {
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int displayWidth = display.getWidth();

String result =
"<html>"
+ "<meta name=\"viewport\" content=\"target-densitydpi=device-dpi,width=device-width\">"
+ "<head>"
+ " <title>Title</title>"
+ "</head>"
+ "<body>"
+ "<image id=\"myImage\" src=\"drawable/image.jpg\" width=\"" + displayWidth + "px\" />"
+ "</body>"
+ "</html>";
return result;
}

I added this method to my Activity and used it to generate the code matching the device it runs on. The onCreate() method now can be pretty straightforward:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manual);

WebView webView = (WebView)findViewById(R.id.webView);

webView.loadDataWithBaseURL("file:///android_res/", generatePage(), "text/html", "utf-8", null);
webView.getSettings().setBuiltInZoomControls(true);
}

Important note: There are two details that you need to keep in mind, or it won't work.

  1. You need to use the method webView.loadDataWithBaseURL(...), otherwise you can't access the local android ressources inside the HTML. This way the src attribute couldn't point to your image file.

  2. You need the tag <meta name="viewport" content="..."> inside your HTML code, and it has to include target-densitydpi=device-dpi inside its content attribute. Otherwise the size of the image may still not match your viewport.

Note: You also can specify a minimal-scale inside the viewporttag, and this really affected my webview. The bad thing: At least on my Galaxy S3 mini running Jelly Bean 4.1.2 a minimal-scale of less than 1.0 had no effect.

Scale down WebView initial scale

When you use user-scalable=no the ability to zoom is disabled. If you don't have access to change this from the web page source the only possible solution is to change the Viewport Content property using Javascript when the page is finished loaded. To allow this you have to set setJavaScriptEnabled(true);

webView = (WebView) findViewById(R.id.webview);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//Option 1: change the viewport content after the page is finished loaded and set initial-scale=0.93 and user-scalable=yes
view.loadUrl("javascript:document.getElementsByName('viewport')[0].setAttribute('content', 'width=device-width, initial-scale=0.93, maximum-scale=0.93, user-scalable=yes');");

//Option 2: change the body zoom style to the initial value you want eg: 0.93 (93%)
//view.loadUrl("javascript:document.body.style.zoom = "+String.valueOf(0.93)+";");
}
});
//load the url
webView.loadUrl(url);


Related Topics



Leave a reply



Submit