How to resize a android webview after adding data in it
In a layout (linear, vertical) hierarchy I've got several views and one of them is a WebView. They all have same parameters:
android:layout_width="fill_parent"
android:layout_height="wrap_content"
For all views, the spacing between elements is correctly handled but for the Webview there is a lot of spaces after the displayed text inside.
I set the (HTML) text of the webview in the "onCreate" method of the activity using the layout.
Is there a way to let the webview resize itself, to match its content size?
By the way, the space left vary from one device to another (emulator vs Milestone vs Hero)
Any idea? Thanks
Asked by: Kelvin233 | Posted: 20-01-2022
Answer 1
I am sure this is too late but adding the method which worked for me in case somebody else comes here looking for solution.
Once the page finishes loading, I am injecting a javascript method to callback me JS hook. And in this method I am passing the size of .
private void setupWebView() {
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
webView.loadUrl("javascript:MyApp.resize(document.body.getBoundingClientRect().height)");
super.onPageFinished(view, url);
}
});
webView.addJavascriptInterface(this, "MyApp");
}
@JavascriptInterface
public void resize(final float height) {
MyActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
webView.setLayoutParams(new LinearLayout.LayoutParams(getResources().getDisplayMetrics().widthPixels, (int) (height * getResources().getDisplayMetrics().density)));
}
});
}
The same solution can also be seen here.
Answered by: Alissa210 | Posted: 21-02-2022Answer 2
It seems that at the moment the Webview only resizes itself if the content is too big. If the webview is bigger then the content it doesn't shrinks to reclaim the space.
Answered by: Clark206 | Posted: 21-02-2022Answer 3
I had the same problem. I solved by changing the visibility of the WebView.
mWebView.setVisibility(View.GONE);
mWebView.loadData(".....");
mWebView.reload();
mWebView.setVisibility(View.VISIBLE);
Answered by: Freddie787 | Posted: 21-02-2022
Answer 4
After some hours of searching and trying I found the simplest working solution. Just call this as "repaint":
webView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
For my webview it works perfectly inside a scrollView. If you do not want to use WRAP_CONTENT, you can use your own params.
Answered by: Rafael725 | Posted: 21-02-2022Answer 5
I only put the webview inside the ScrollView and set layout_height=wrap_content and it worked.
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/web_scrollview"
android:layout_below="@id/question_title_section"
android:layout_marginBottom="60dp"
android:scrollbars="vertical">
<WebView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/question_content"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:padding="4dp">
</WebView>
</ScrollView>
And in my Activity
wvQuestion = (WebView) findViewById(R.id.question_content);
wvQuestion.loadUrl(url);
Answered by: Melissa329 | Posted: 21-02-2022
Answer 6
I found:
(1) there are two height in webview. MeasureHeight and contentHeight. Note that the contentHeight is computed from the webcoreThread. The two height are not consistent any time!
(2) when layout finish.the webview reload content. The contentHeight is consistent with measureHeight.
So I think one solution is: make webview reload content after the layout finished.
My solution:
(1)extends webview . (2)override onlayout(),dispatchDraw(),
@Override
protected void dispatchDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.dispatchDraw(canvas);
//mchanged == is parameter in onlayout()
//finished == have run the code below !
if (!mchanged && !finished) {
//
String vHtml =".........." ;//your html content
this.loadDataWithBaseURL("目录æµè§ˆ", vHtml, "text/html", "utf-8", null);
finished = true;
}
}
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
// tttttt
if (!changed) {
this.mchanged = changed;//false
}
}
(3) webview need init before load every content.
public void intiFlag() {
mchanged = true;
finished = false ;
}
Hope this helps.
Answered by: Miranda585 | Posted: 21-02-2022Answer 7
You can periodically update WebView height according to javascript body height, like this:
public class WrapContentWebView extends WebView {
private static final long UPDATE_INTERVAL = 100; // ms
public WrapContentWebView(Context context) {
super(context);
init();
}
public WrapContentWebView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public WrapContentWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
addJavascriptInterface(new JavascriptInterface(), "java");
postDelayed(scheduleRunnable, UPDATE_INTERVAL);
}
private Runnable scheduleRunnable = new Runnable() {
@Override
public void run() {
loadUrl("javascript:window.java.onNewHeight(document.body.offsetHeight);");
postDelayed(scheduleRunnable, UPDATE_INTERVAL);
}
};
private class JavascriptInterface {
@android.webkit.JavascriptInterface
public void onNewHeight(String bodyOffsetHeight) {
if (bodyOffsetHeight == null) {
return;
}
final int newHeight =
(int) (Integer.parseInt(bodyOffsetHeight) *
getScaleY() *
getResources().getDisplayMetrics().density);
if (getLayoutParams().height != newHeight) {
((Activity) getContext()).runOnUiThread(new Runnable() {
@Override
public void run() {
getLayoutParams().height = newHeight;
requestLayout();
}
});
}
}
}
}
layout.xml:
<WrapContentWebView
android:layout_width="match_parent"
android:layout_height="0dp">
</WrapContentWebView>
P.S. Checked on Android 5, 4.1, 4.04
Answered by: Agata706 | Posted: 21-02-2022Answer 8
I also had the problem of the WebView not sizing to fit after adjusting text size via javascript. I solved this by setting the visibility of the WebView to View.GONE until onPageFinished(). After the page loads and I tweak font size etc via javascript, setVisibility(View.VISIBLE) and the WebView sizes to fit perfectly.
webView.setVisibility(View.GONE);
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url)
{
int jsSize = (int)fBioTextSize; //a double set in the owning class...
String sizeTweak = "" ;
if (jsSize > 0.00)
{
sizeTweak =
"document.getElementsByTagName('body')[0].style.fontSize = '" + jsSize + "px'; ";
}
view.loadUrl("javascript:(function() { " +
"document.getElementsByTagName('body')[0].style.color = '#9e9e9e'; " +
"document.getElementsByTagName('body')[0].style.background = 'black'; " +
sizeTweak +
"})()");
view.setVisibility(View.VISIBLE);
}
});
Answered by: Adelaide635 | Posted: 21-02-2022
Answer 9
If you simply remove the view and then add a new one back, problem solved.
Here is an example:
WebView current_view = (WebView) view.getChildAt(i);
CharSequence current_text = current_view.getText();
int index = parent.indexOfChild(current_view);
parent.removeView(current_view);
current_view = new WebView(context);
parent.addView(current_view, index, layoutParams);
current_view.loadDataWithBaseURL( ...however you want... );
view.invalidate();
In summary... it just adds a new WebView just like the old right back to its parent at the same index.
Answered by: Rafael814 | Posted: 21-02-2022Answer 10
I had similar problem with FrameLayout containing TextView, ProgressBar and WebView. Depends on the return object from server I was hiding views and sometimes when I had to show web page and hide TextView and ProgressBar in onPageFinished() WebView had a hight of ProgressBar. Manage to fix it by this piece of code:
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
new Handler().post(new Runnable() {
@Override
public void run() {
progressBar.setVisibility(View.GONE)
}
});
}
Answered by: Madaline197 | Posted: 21-02-2022
Answer 11
Agree with @Fernwilter. But changing the sequence worked for me.
mWebView.setVisibility(View.GONE);
mWebView.reload();
mWebView.setVisibility(View.VISIBLE);
mWebView.loadData(".....");
Answered by: Catherine895 | Posted: 21-02-2022
Answer 12
It worked for me.
ViewTreeObserver viewTreeObserver = dataWebView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (dataWebView.getMeasuredHeight() > 0) {
dataWebView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
((Activity) getContext()).runOnUiThread(() -> {
dataWebView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0));
dataWebView.setVisibility(View.GONE);
dataWebView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
dataWebView.setVisibility(View.VISIBLE);
});
}
}
});
Answered by: Paul711 | Posted: 21-02-2022
Answer 13
After trying several ways, finally this worked for me: +++first use useState:
const [height, setHeight] = useState(0)
+++declare:
const webViewScript = `
setTimeout(function() { window.ReactNativeWebView.postMessage(document.documentElement.scrollHeight);}, 500);
true;
`
+++Next we wrap a View into the webview:
<View style={{ width: "100%", height: height }}>
<WebView
originWhitelist={["*"]}
source={{ html: html }}
onMessage={(event) => {
setHeight(parseInt(event.nativeEvent.data))
}}
javaScriptEnabled={true}
injectedJavaScript={webViewScript}/>
</View>
Answered by: Lana728 | Posted: 21-02-2022
Answer 14
A little bit complicated but working ...
private ViewGroup mScrollView //linearlayout encapsuled in a scrollView;
private WebView mWebView;
private Handler mHandler = new Handler(){
public void handleMessage(Message msg){
mWebView.reload();
mScrollView.addView(mWebView, 0);
}
};
private updateWebView(){
//update the content of your web view
mScrollView.removeView(mWebView);
mWebView.clearView();
mHandler.sendMessageDelayed(mHandler.obtainMessage(0), 200);
}
Answered by: Aida675 | Posted: 21-02-2022
Answer 15
An easier solution is to invalidate the webview once loading has finished:
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(final WebView view, final String url) {
super.onPageFinished(view, url);
webView.invalidate();
}
});
Answered by: Rebecca712 | Posted: 21-02-2022
Similar questions
android - webview showing white bar on right side
I am giving the following method call to my webview client embedded in my layout
wv.loadData("<html><body bgcolor=\"Black\"></body></html>","text/html", "utf-8");
when i run this on the device, it shows a white vertical bar on the right side. I fixed the white thing by using webview.setBackgroundColor(Color.BLACK); but i want to remove it completely
Fo...
android - Set zoom for Webview
I have a WebView and 2 urls to open it it. What I want to do is, when i set a zoom level for 1st url, and then i go to 2nd url, it should also have the same zoom level. Right now, the zoom level resets for both.
Thanks,
Farha
android - Getting WebView content, or cookies
Is there a way to get the current content of a WebView?
What about Cookies for a specific host+url?
android - Can I make the webview take only a part of the screen?
I am trying to make a webview to open on the bottom of the application to display little information but it keeps taking the whole screen and covering other widgets with information.
Is there a way to make it have a certain size and place on the application?
android - Adjust text size of WebView?
I would like to proportionally decrease the size of all text in a WebView as easily as possible. I've tried android:textSize="..." without success. Api Level 7.
android - digital compass problem
I am creating an augmented reality application and I noticed that the stored locations don't appear appear on the correct direction if I try to use the camera view (using layar or wikitude API).
The problem is that the digital compass doesn't show north correctly when you try to look at the known objects through the camera view. If align the phone with the ground (look at my shoes) the locations appear at the screen accord...
android - How to remove labels from a MapView?
I am trying to make a satellite view (via a MapView) without labels. How can I do this?
android - Custom title with image
i'm creating custom title for activity by disabling standard one and managing everything myself. I wonder if it's possible to replace/theme standart title to my needs.
I can customize size, background image, and text via themes by changing windowXYZStyle items.
The only thing i couldn't find - how i can add image instead of text.
I've tried requestWindowFeature(Window.FEATURE_CUSTOM_TITLE)
and ...
canvas - Android draw with blur
I need do draw on Android's Canvas using Blur effect,
it is a very simple feature,
I need to draw a circular area, which is blurred (the foreground) and the background transparent, I can do everything with manipulating the colour alpha to do it with custom transparency but I need it to be blurred instead of transparent..
any ideas?
How to find easily the source of an android class
I know I can access android source code from https://android.googlesource.com, but it's hard to select the right git repo if I only know the package and the name of an android class.
Isn't there a way to locate a file in https://android.googlesource.com?
camera - Android Intent Save Path
At the moment I am using two intents. One for voice-recording, another for the camera:
Intent photoIntent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(photoIntent, ACTIVITY_TAKE_PHOTO);
Intent voiceIntent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
startActivityForResult(voiceIntent, ACTIVITY_RECORD_SOUND);
My aim is to put an Extra to each of t...
Android "hover" event in custom layout
I have a custom layout that I have written that basically just displays a bunch of ImageViews. I am handing onTouch events for all the ImageViews in my layout.
However, if a user touches one imageView and then drags over another ImageView, I would like to be able to handle that as well.
How would I go about capturing this behaviour?
android - What is the ideal place to cache images?
I am fetching a lot of thumbnails in my application from a remote server and lazy-loading these in a list view.
The image fetches run in a background AsynTask and when completed the fetched images are stored in a HashMap using SoftReferences.
This works just fine but when the images in the cache gets GC’d, the fetches have to be rerun.
I could have stored them on the SD card so there would be no...
How to create a tree view in Android?
There are no controls in Android that provide Tree-like View. There is an ExpandableList View which I suspect could be used to creating one.
Have you tried imlpementing such a control?
How would one implement such a control in Android?
android how to scroll to see all the widget of the view
In one of my androids activities, I have several widget in a vertical linearlayout. The length of this layout is bigger than the screen and thus I cannot see the widget at the bottom.
In the Emulator, is there a special scroller to implement or a particular action to do to be able to scroll up and down ?
Thanks a lot,
Luc
Still can't find your answer? Check out these communities...
Android Google Support | Android Community | Android Community (Facebook) | Dev.io Android