Android get height of webview content once rendered
You can use ViewTreeObserver
on that WebView
to get actual height after rendering its content.
here's the sample code.
ViewTreeObserver viewTreeObserver = mWebView.getViewTreeObserver();
viewTreeObserver.addOnPreDrawListener(new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
int height = mWebView.getMeasuredHeight();
if( height != 0 ){
Toast.makeText(getActivity(), "height:"+height,Toast.LENGTH_SHORT).show();
mWebView.getViewTreeObserver().removeOnPreDrawListener(this);
}
return false;
}
});
Need help get content view height - Android
The best way I found to get contentHeight after rendering :
Create your own class extended WebView and this class in your layout :
public class BKWebView extends WebView {
private Activity yourActivity;
public BKWebView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public BKWebView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public BKWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
public void invalidate() {
super.invalidate();
if (getContentHeight() > 0) {
// WebView has displayed some content and is scrollable.
if (yourActivity != null)
yourActivity.callBackWebView(getContentHeight());
}
}
/**
* @param yourActivity the yourActivity to set
*/
public void setYourActivity(Activity yourActivity) {
this.yourActivity = yourActivity;
}
}
in your activity implement the callback method and then in your listener :
private webViewContentHeight;
BKWebView wv;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
wv = (BKWebView) findViewById(R.id.yourwebview);
wv.setYourActivity(this);
...
}
public void callBackWebView(int contentHeight) {
webViewContentHeight = contentHeight;
}
...
Button btn = (Button) this.getActivity().findViewById(R.id.btnCLick);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("Get my custom webView content height", " " + webViewContentHeight);
}
});
...
How to get the full height of in android WebView?
Finally I got the answer for my question. Here is the answer.
After loading WebView
we will get call in WebViewClient#onPageFinished
there we need to call javascript to get the height of full content of WebView
WebViewClient
class
/**
* Custom web client to perform operations on WebView
*/
class WebClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript:AndroidFunction.resize(document.body.scrollHeight)");
}
}
}
After that we will get callback with height in WebInterface
class which is Registered as JavascriptInterface
/**
* WebView interface to communicate with Javascript
*/
public class WebAppInterface {
@JavascriptInterface
public void resize(final float height) {
float webViewHeight = (height * getResources().getDisplayMetrics().density);
//webViewHeight is the actual height of the WebView in pixels as per device screen density
}
}
How to update custom WebView height request when content is shrunk
I found a way to do it based on this thread.
I first tried with a JS command that returns the body height : document.body.scrollHeight
.
The problem was the same, it always returned the largest size, but never decreased the size.
As the JS command have no problem to increase the size, I had to set the height to 0, set a 100ms delay (arbitrary) and then get the height of the HTML with the JS command above and set the HeightRequest
of the view.
With this, the HTML body height will not decrease... It will always start from 0 and increase to the HTML body size.
Final result :
public class AutoHeightWebViewRenderer : WebViewRenderer
{
static AutoHeightWebView _xwebView = null;
public AutoHeightWebViewRenderer(Android.Content.Context context) : base(context)
{
}
class DynamicSizeWebViewClient : WebViewClient
{
public async override void OnPageFinished(Android.Webkit.WebView view, string url)
{
try
{
if (_xwebView != null)
{
view.Settings.JavaScriptEnabled = true;
view.Settings.DomStorageEnabled = true;
_xwebView.HeightRequest = 0d;
await Task.Delay(100);
string result = await _xwebView.EvaluateJavaScriptAsync("(function(){return document.body.scrollHeight;})()");
_xwebView.HeightRequest = Convert.ToDouble(result);
}
base.OnPageFinished(view, url);
}
catch (Exception ex)
{
Console.WriteLine($"{ex.Message}");
}
}
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
_xwebView = e.NewElement as AutoHeightWebView;
if (e.OldElement == null)
{
Control.SetWebViewClient(new DynamicSizeWebViewClient());
}
}
}
Android WebView getContentHeight() doesnt return the correct value
I found the issue with this after some research. Webview usually scales the web page based on the screen size and then renders it. It usually zooms the page so that it doesn't look too small in the phone. You can get this scale factor by using the method getScale()
So, in my case, i would use the following condition to check whether end of page has been reached
(getContentHeight()*getScale() - (top + getHeight())) <= mMinDistance)
//mMinDistance is 0 in my case
Android Webview - Webpage should fit the device screen
You have to calculate the scale that you need to use manually, rather than setting to 30.
private int getScale(){
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth();
Double val = new Double(width)/new Double(PIC_WIDTH);
val = val * 100d;
return val.intValue();
}
Then use
WebView web = new WebView(this);
web.setPadding(0, 0, 0, 0);
web.setInitialScale(getScale());
Related Topics
Safely Generate Random Numbers Between Some Range in Java
Most Efficient Solution for Reading Clob to String, and String to Clob in Java
How to Specify the Path for Getresourceasstream() Method in Java
Parsing the Nested Json Array Using Jackson Library in Java
How to Execute SQL Script File in Java
How to Parse a Json Input Stream
Run Gradle Task With Spring Profiles (Integration Tests)
How to Input Date Using Sendkeys in Selenium Webdriver
Parse a Uri String into Name-Value Collection
Java Xmlbeans Throws Nosuchmethod Error
Why Is Git Bash Not Using the Correct Java Path as Defined in the Path Environment Variable
I Want to Execute Code Every X Seconds, But Handler.Postdelayed Not Working
Simple Export and Import of a Sqlite Database on Android