Reputation: 1412
I have a strange problem with a WebView I want to use to display an image and make it zoomable. I have the following method within my Activity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manual);
WebView webView = (WebView)findViewById(R.id.webView);
webView.loadUrl("file:///android_res/drawable/some_image.jpg");
webView.setInitialScale(getScale());
webView.getSettings().setBuiltInZoomControls(true);
}
The getScale()
method computes a scale I can use with webView.setInitialScale()
to exactly scale my image to full screen width, and it works. The builtin zoom controls also work to some extent, but:
After I zoomed into the image, I can't zoom out back to my initial scale, I assume because the minimum scale is greater than my initial scale.
Setting the zoom density using WebSettings doesn't help, and I think even if it did on my phone it wouldn't on another.
What I also tried: I made an HTML-Page containing the image as only child of the body element. I set its width to 100% and also got it scaled right that way. However if I zoom in again, the image immediately is resized to again fit the screen width.
I found some answers, but none of them really helped:
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setDefaultZoom(ZoomDensity.FAR);
webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
One solution mentioned employing reflection to change the WebView class to ignore the limits, but I fear this could break my app on some older versions of Android. I have to be compatible with devices down to API level 9.
Upvotes: 2
Views: 9672
Reputation: 929
May be this is what your are searching
settings.setBuiltInZoomControls(true);
settings.setSupportZoom(true);
settings.setUseWideViewPort(true);
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
Upvotes: -2
Reputation: 1412
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.
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.
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 viewport
tag, 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.
Upvotes: 3