[英]Android get height of webview content once rendered
我試圖在渲染后獲得webview的高度。 它總是返回null,我嘗試過getHeight
, getMeasuredHeight
, getContentHeight
,它總是返回null。
布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/instructions"
android:background="@color/transparent_black" >
<WebView
android:id="@+id/top_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
活動
public class TestActivity extends MenuActivity {
private final static String TAG = "HearingTest";
private String urlTopContent;
private WebView topContent;
private boolean mMoreInfoTop = true;
private int mYdelta = 0;
private int mBottomOffset = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.right_hearing_test);
String topHtml = this.getString(R.string.top_content);
//String bottomHtml = this.getString(R.string.bottom_content);
urlTopContent = "file:///android_asset/html/" + topHtml;
WebViewSettings();
LoadWebPage(urlTopContent);
}
public void WebViewSettings(){
topContent = (WebView) findViewById(R.id.top_content);
topContent.getSettings().setJavaScriptEnabled(true);
topContent.getSettings().setBuiltInZoomControls(true);
topContent.getSettings().setSupportZoom(true);
topContent.getSettings().setLoadWithOverviewMode(true);
topContent.setBackgroundColor(0);
topContent.canGoBack();
int topHeight = topContent.getContentHeight();
Log.d("Top Height", "Height: " + topHeight);
topContent.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getHost().equals(urlTopContent)) {
// This is my web site, so do not override; let my WebView load the page
return false;
}
// Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
View webViewHeight = (View) findViewById(R.id.top_content);
int height = webViewHeight.getHeight();
Log.d("Top Content","Top Content Height:" + height);
}
});
}
public void LoadWebPage(String url){
try {
topContent.loadUrl(url);
Log.d("Loading Web Page", "URL" + url + "connected");
}
catch (Exception e) {
Log.d("Loading Web Page", "URL: " + url + " couldn't connect.");
}
}
}
我甚至不知道在渲染后是否可以獲得Web視圖的高度,但我不明白為什么你不能。 如果任何人得到和解決方案,將不勝感激。
您可以在該WebView
上使用ViewTreeObserver
在呈現其內容后獲取實際高度。
這是示例代碼。
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;
}
});
我發現這個解決方案100%可靠。
對WebView進行子類化,並且需要在加載內容后調用javascript 。
// callback made this way in order to get reliable html height and to avoid race conditions
@SuppressLint("SetJavaScriptEnabled")
override fun onPageFinished(view: WebView?, url: String?) {
view?.let {
it.settings.javaScriptEnabled = true
it.addJavascriptInterface(WebAppInterface(it), "AndroidGetHeightFunction")
it.loadUrl("javascript:AndroidGetHeightFunction.resize(document.body.scrollHeight)")
}
}
然后我們可以獲得適當的高度並在回調中禁用javascript (為了安全性和一致性):
inner class WebAppInterface(private val webView: WebView) {
@JavascriptInterface
fun resize(height: Float) {
webView.post {
heightMeasuredListener?.invoke(formatContentHeight(webView, height.toInt()))
webView.settings.javaScriptEnabled = false
}
}
}
WebView 必須調用post(),因為在WebView線程中調用resize(...)中的代碼!
之后,請務必縮放像素以匹配密度像素 !:
fun formatContentHeight(webView: WebView, height: Int): Int = Math.floor((height * webView.context.resources.displayMetrics.density).toDouble()).toInt()
我選擇了這種方法
const val heightWebViewJSScript = "(function() {var pageHeight = 0;function findHighestNode(nodesList) { for (var i = nodesList.length - 1; i >= 0; i--) {if (nodesList[i].scrollHeight && nodesList[i].clientHeight) {var elHeight = Math.max(nodesList[i].scrollHeight, nodesList[i].clientHeight);pageHeight = Math.max(elHeight, pageHeight);}if (nodesList[i].childNodes.length) findHighestNode(nodesList[i].childNodes);}}findHighestNode(document.documentElement.childNodes); return pageHeight;})()"
webView.webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView, url: String) { webView.evaluateJavascript(heightWebViewJSScript ) { height -> val params = itemView.layoutParams // params.height } } }
試過並測試了以下內容:
mWebView = new WebView(this);
mWebView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View view, int l, int t, int r, int b, int ol, int ot, int or, int ob) {
Log.i("demo", String.format("%s: top=%d, bottom=%d, content height=%d",
Thread.currentThread().getStackTrace()[2].getMethodName(), t, b, mWebView.getContentHeight()
));
}
});
日志:
12-20 16:08:33.969 1466-1466 / yourPkg I / demo:onLayoutChange:top = 0,bottom = 0,content height = 0
12-20 16:08:33.970 1466-1466 / yourPkg I / demo:onLayoutChange:top = 0,bottom = 0,content height = 0
12-20 16:08:34.061 1466-1466 / yourPkg I / demo:onLayoutChange:top = 0,bottom = 1510,content height = 0
12-20 16:08:34.091 1466-1466 / yourPkg I / demo:onLayoutChange:top = 0,bottom = 1510, content height = 2050
最后一個是正確的。
ViewTreeObserver
有時會給我錯誤的高度。
沒關系,這是相當晚,但我覺得它很好的解決方案,只需使用if (webView.getContentHeight() > 0)
如果ture
這意味着它finsihed,否則,它尚未完成
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.