In some web browsers, huge images are automatically resized to fit the screen.
Is it possible to do the same in an Android WebView?
The web page just contains the image, maybe adding some JavaScript could do the trick?
Anybody has already done this?
Note: I don't know the size of the image in advance.
Yes, it's possible. You can try setting the WebView Layout using the code below. It resizes all Images (Greater than the Device Screen Width) to the Screen Width. This works for both Orientations (Portrait and Landscape)
webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
You can add extra margins/padding later to get the spacing right.
webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
works but is deprecated. This is another solution without LayoutAlgorithm.SINGLE_COLUMN, using CSS:
#SuppressLint("NewApi")
private openWebView() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.TEXT_AUTOSIZING);
} else {
webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
}
String data = "<div> your HTML content </div>";
webView.loadDataWithBaseURL("file:///android_asset/", getHtmlData(data), "text/html", "utf-8", null);
}
private String getHtmlData(String bodyHTML) {
String head = "<head><style>img{max-width: 100%; width:auto; height: auto;}</style></head>";
return "<html>" + head + "<body>" + bodyHTML + "</body></html>";
}
You could use this:
WebView webView = (WebView) findViewById(R.id.myWebView);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);
Found this solution here:
How to set the initial zoom/width for a webview
You can have the browser resize the image for you to fit the maximum width of the screen:
<img src="huge-image.jpg" width="100%" />
Resizing its height to WebView's viewport is possible too:
<img src="huge-image.jpg" height="100%" />
However, resizing both width and height would result in a stretched image. To either resize the width or height depending of what side fits best you may consider a bit of JavaScript, like this:
<img src="huge-image.jpg" onload="resize(this);" />
<script type="text/javascript">
function resize(image)
{
var differenceHeight = document.body.clientHeight - image.clientHeight;
var differenceWidth = document.body.clientWidth - image.clientWidth;
if (differenceHeight < 0) differenceHeight = differenceHeight * -1;
if (differenceWidth < 0) differenceWidth = differenceWidth * -1;
if (differenceHeight > differenceWidth)
{
image.style['height'] = document.body.clientHeight + 'px';
}
else
{
image.style['width'] = document.body.clientWidth + 'px';
}
// Optional: remove margins or compensate for offset.
image.style['margin'] = 0;
document.body.style['margin'] = 0;
}
</script>
I faced the same problem and used Jsoup to help me out and add the required respected CSS. You can easily add attributes or CSS. I my case, I download from many sources various different HTML files, save them and then display them in a Webview. Here is how I parse the HTML before I save it to the database with Kotlin:
// Parse your HTML file or String with Jsoup
val doc = Jsoup.parse("<html>MY HTML STRING</html>")
// doc.select selects all tags in the the HTML document
doc.select("img").attr("width", "100%") // find all images and set with to 100%
doc.select("figure").attr("style", "width: 80%") // find all figures and set with to 80%
doc.select("iframe").attr("style", "width: 100%") // find all iframes and set with to 100%
// add more attributes or CSS to other HTML tags
val updatedHTMLString = doc.html()
// save to database or load it in your WebView
Add Jsoup to your project
Have fun!
If your WebView width is fill_parent then you can use this code:
Display display=getWindowManager().getDefaultDisplay();
int width=display.getWidth();
String data="<img src='http://example.com/image.jpg' style='width:"+width+"px' />";
webView.loadData(data, "text/html", "utf-8");
And zoom still working!
Same method if height is fill_parent.
My favorite's :
String data = "<html><body ><img id=\"resizeImage\" src=\""+PictureURL+"\" width=\"100%\" alt=\"\" align=\"middle\" /></body></html>";
webview.loadData(data, "text/html; charset=UTF-8", null);
You could send the size you want in the request parameters and let the server set the width/height in the img element for you.
Related
I create a service that loads data from a remote server and returns HTML data. This data I put to my WebView. All work good but have one problem: If some word is too long, WebView adds horizontal scroll. I add CSS file with break-work, word-wrap but it doesn't help.
JSONObject jsonObject = new JSONObject(strResult);
String content = jsonObject.getString("postContent");
TextView postTitle = (TextView) view.findViewById(R.id.postTitle);
postTitle.setText(jsonObject.getString("postTitle"));
WebView postContent = (WebView) view.findViewById(R.id.postContent);
postContent.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
postContent.getSettings().setLoadWithOverviewMode(true);
postContent.getSettings().setUseWideViewPort(true);
postContent.getSettings().setBuiltInZoomControls(true);
postContent.getSettings().setJavaScriptEnabled(true);
postContent.loadDataWithBaseURL("file:///android_asset/", content, "text/html; charset=utf-8", "utf-8", null);
I did face completely similar problems and finally realized that I misused the css options for that. Just add word-break: break-all; word-break: break-word to css style for body and/or headers and it's done
<head>
<style type="text/css">
body {text-align: center; word-break: break-all; word-break: break-word}
h1 {font-size:large; word-break: break-all; word-break: break-word}
h2 {font-size:medium; word-break: break-all; word-break: break-word}
</style> </head>
Some more details for css properties can be found here or there
Please be careful, as word-break option could seriously impact the readability of the text in WebView. Only use it when you really need it.
Apparently:
setLoadWithOverviewMode(true) loads the WebView completely zoomed out
setUseWideViewPort(true) makes the Webview have a normal viewport (such as a normal desktop browser), while when false the webview will have a viewport constrained to its own dimensions (so if the webview is 50px*50px the viewport will be the same size)
so i recommend you don't use setUseWideViewPort, the following code is for similar task that worked good:
final WebSettings webSettings = webView.getSettings();
webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
webSettings.setEnableSmoothTransition(true);
webView.setBackgroundColor(Color.parseColor("#00000000"));
String before = "<html><head><style type=\"text/css\">#font-face {font-family: MyFont;src: url(\"file:///android_asset/fonts/w_yekan.ttf\")}body {font-family: MyFont;font-size: 14px;text-align: right;}</style></head><body><div style=\"direction:rtl !important;; text-align:right !important;\">";
String after = "</body></html>";
String myHtmlString = before + Utils.editString(DoaText) + after;
webView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);
webView.loadDataWithBaseURL(null, myHtmlString, "text/html", "UTF-8", null);
i hope this answer be a good solution for you .
I am working on a reader and I have an issue with latest generation of android devices which comes with high resolution. The pictures on webViews are showing very small, while on older devices their size seemed acceptable. I cannot manipulate the content of the HTML files, I can only manipulate the webView's settings and the .css file linked to the webView.
Initially when I open the book the image shows very small, but when I manipulate the image it gets over magnified and becomes trimmed in both sides.
img
{
max-width: 100%;
width:auto;
height: auto;
}
I also tried:
img
{
min-width: 100%;
height: auto;
}
This is the webView settings:
testWV = (WebView) findViewById(R.id.mywebview1);
testWV.setDelegate(this);
testWV.setVerticalScrollBarEnabled(false);
testWV.setHorizontalScrollBarEnabled(false);
testWV.getSettings().setDefaultZoom(ZoomDensity.FAR);
Okay, try this, you may remove the head tag if you wish, the style is the important part
String content = "Your Content"; // I assume your content is a string
testWV = (WebView) findViewById(R.id.mywebview1);
testWV.setDelegate(this);
testWV.setVerticalScrollBarEnabled(false);
testWV.setHorizontalScrollBarEnabled(false);
testWV.getSettings().setDefaultZoom(ZoomDensity.FAR);
String head = "<head><meta name='viewport' content='target-densityDpi=device-dpi'/></head>";
String style = "<style> " +
"img { height:auto !important; width:100% !important; } " +
"</style>";
testWV.loadDataWithBaseURL("", head + style + content, "text/html", "UTF-8", "");
I have a math equation as a text WebView that I need to fit the entire screen no matter its dimensions.. my first intuition of doing this is simply shrinking the text whenever it gets out of bounds so that it remains constrained, however, I can't find any functions or methods to actually MEASURE the content of that webview, I've tried:
webview.getMeasuredHeight, webview.getHeight
but the issue with them is that they are constantly affixed on the size of the webview widget, not on the content, so I moved to:
webview.getContentHeight
which seemed to work, the problem is it works only after the text is "loaded", so it doesn't get the right answer at first, even if it's called in onPageFinished.
My questions are:
1) Is there a way to know the content size of the TEXTUAL html webview?? I would even appreciate knowing the scroll bar length that would indicate size.
2) Is there a listener function that would enable me to run code from the moment the text actually loaded? The webview declaration looks something like this:
webView = (WebView) findViewById(R.id.webView);
js = "<html><head>"
+ "<link rel='stylesheet' href='file:///android_asset/mathscribe/jqmath-0.4.3.css'>"
+ "<script src='file:///android_asset/mathscribe/jquery-1.4.3.min.js'></script>"
+ "<script src='file:///android_asset/mathscribe/jqmath-etc-0.4.3.min.js'></script>"
+ "</head><body>"
+ "<script>var s = '$$" + functext + "$$';M.parseMath(s);document.write(s);</script> </body>";
webView.loadDataWithBaseURL("", js, "text/html", "UTF-8", "");
The text does not load instantly, so the code relating to it is usually flawed.
3) Is there a webview.getContentWidth or something of the like?
EDIT:
This code may help you in fitting your wepage to webview.
webview.getSettings().setLoadWithOverviewMode(true);
webview.getSettings().setUseWideViewPort(true);
You have to calculate the scale so that content fits on the screen.
private int getScale()
{
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth();
Double val = new Double(width)/new Double(Your_webpage_width);
val = val * 100d;
return val.intValue();
}
Then use
WebView web = new WebView(this);
web.setPadding(0, 0, 0, 0);
web.setInitialScale(getScale());
2) To run something after webview has completely loaded,just implement WebViewClient and extend onPageFinished() as follows:
mWebView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// do your stuff here
}
});
I'm developing an Android application in which I have used an HTML file for help contents. I have used a WebView to display the content and every thing is fine.
The problem is that user can change the theme and font size of the application. How can I propagate these properties to the content of WebView? Exactly how can I change the font size and text color in WebView? Is there a simple way to do that or I should create different HTMLfiles or CSSes? How to handle the size units (dp, sp, ...)?
I will appreciate your help with this situation.
loadUrl("javascript:(document.body.style.backgroundColor ='red');");
loadUrl("javascript:(document.body.style.fontSize ='20pt');");loadUrl("javascript:(document.body.style.color ='yellow');");
On your android application, use following code to load a web page with user chosen font size and color:
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebChromeClient(new InredisChromeClient(this));
myWebView.setWebViewClient(new InredisWebViewClient(this));
myWebView.clearCache(true);
myWebView.clearHistory();
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
myWebView.loadUrl("http://demo.com/content.html?font-size=12&fontcolor=blue");
On the content.html page, enable JavaScript and use jQuery and its function as below:
function getCssValue(sCSS)
{
var sPageURL = window.location.search.substring(1);
var sValues = sPageURL.split('&');
for (var i = 0; i < sValues.length; i++)
{
var sPair = sValues[i].split('=');
if (sPair[0] == sCSS)
{
return sPair[1];
}
}
}
$(document).ready(function(){
// Set the Font Size from URL
$('html').css('font-size', getCssValue('font-size'));
});
It is best to do theme activities using CSS and Javascript. However if we want to pass on some settings from Android to the WebView dynamically, it is possible and a solution is to use the JavascriptInterface. Here is one way of doing it:
Firstly, we define a class which will be used as a bridge between the Android app and the WebView for JS interactions.
Here WebInterface is an inner class in the Activity and hence it has direct access to myWebView, which is a WebView instance variable.
public class WebInterface {
private Activity activity;
public WebInterface(Activity activiy) {
this.activity = activiy;
}
#JavascriptInterface
public void changeTheme() {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// All of the theme settings could go here, the settings passed on by Android
myWebView.loadUrl("javascript:document.body.style.backgroundColor ='red';");
myWebView.loadUrl("javascript:document.body.style.fontSize ='20pt'");
myWebView.loadUrl("javascript:document.body.style.color ='yellow';");
//OR load your data as shown here http://stackoverflow.com/a/7736654/891092
htmlData = "<link rel=\"stylesheet\" type=\"text/css\" href=\"theme.css\" />" + htmlData;
// lets assume we have /assets/theme.css file
myWebView.loadDataWithBaseURL("file:///android_asset/", htmlData, "text/html", "UTF-8", null);
}
});
}
}
Note that it is very important to run your code in UI Thread otherwise it will not work.
Here is how the Activity registers the WebView with the JavascriptInterface:
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.addJavascriptInterface(jsInterface, "JSInterface");
In the HTML file, which the user is viewing, a button or widget could be made to change theme by calling code in Android through the bridge:
<input type="button" value="Say hello" onClick="doChangeTest()" />
<script type="text/javascript">
function doChangeTest(){
JSInterface.changeTheme(); // this calls the changeTheme in WebInterface
}
</script>
First you need to define a webView and after that use below method.
lightFont is your font that you should store in asset folder.
color is your text color.
font size : you can change font size.(for example 20px or medium and etc).
at the end you need to use seconde method to show html on webView
First Method:
public static String getStyledFont(String html) {
boolean addBodyStart = !html.toLowerCase().contains("<body>");
boolean addBodyEnd = !html.toLowerCase().contains("</body");
return "<style type=\"text/css\">" +
"#font-face {font-family: CustomFont;" +
"src: url(\"file:///android_asset/lightFont.ttf\")}" +
"body {color: #787878;}"+
"body {font-family: CustomFont;font-size: x-small;}</style>" +
(addBodyStart ? "<body>" : "") + html +(addBodyEnd ? "</body>" : "");
}
Second method:
String htmlText = getStyledFont(yourText);
webView.loadDataWithBaseURL("file:///android_asset/",
htmlText ,
"text/html; charset=UTF-8", null, null);
i have an url which has in the html body the following style:
style='width:468px; height:60px;'
I want to add the url in a webview but its content is to big (witdh and height) so i have to resize both.
I tried these solutions(Android Webview - Webpage should fit the device screen, http://developer.android.com/guide/webapps/targeting.html) and no one worked for me. I managed to change the width using:
String javascript = "javascript:document.getElementsByTagName('div')[0].style.width='100%';";
view.loadUrl(javascript);
but it does not work with the height beucase the content is too big. Do you know other ways to do this?
finally i changed the sizes by using the following method:
#Override
public void onPageFinished(WebView view, String url) {
float scale = myWebView.getHeight() / 170f;
myWebView.setInitialScale((int) (scale * 100f));
String js = "javascript:(function(){"
+ "document.getElementsByTagName('div')[0].style.height = 'auto';"
+ "document.getElementsByTagName('div')[0].style.width = 'auto';"
+ "})()";
view.loadUrl(js);
}