在布局(线性,垂直)层次结构中,我有几个视图,其中一个是WebView。 它们都有相同的参数:
android:layout_width="fill_parent"
android:layout_height="wrap_content"
对于所有视图,正确处理元素之间的间距,但对于Webview,在显示的文本内部后面有很多空格。
我使用布局在活动的“onCreate”方法中设置webview的(HTML)文本。
有没有办法让webview自行调整大小以匹配其内容大小?
顺便说一句,剩下的空间因设备而异(模拟器与Milestone vs Hero)
有什么想法吗?感谢
答案 0 :(得分:19)
我确信现在为时已晚,但添加了适合我的方法,以防其他人来这里寻找解决方案。
一旦页面加载完毕,我正在注入一个javascript方法来回调我JS钩子。在这种方法中,我传递的是。
的大小 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)));
}
});
}
也可以看到相同的解决方案here.
答案 1 :(得分:6)
目前看来,如果内容太大,Webview只会自行调整大小。如果webview更大,那么内容不会收缩以回收空间。
答案 2 :(得分:4)
我遇到了同样的问题。我通过改变WebView的可见性解决了这个问题。
mWebView.setVisibility(View.GONE);
mWebView.loadData(".....");
mWebView.reload();
mWebView.setVisibility(View.VISIBLE);
答案 3 :(得分:1)
我找到了:
(1)webview中有两个高度。 MeasureHeight和contentHeight。请注意,contentHeight是从webcoreThread计算的。这两个高度随时都不一致!
(2)布局完成时.webview重新加载内容。 contentHeight与measureHeight一致。
所以我认为一个解决方案是:在布局完成后让webview重新加载内容。
我的解决方案:
(1)扩展了webview。 (2)覆盖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需要init。
public void intiFlag() {
mchanged = true;
finished = false ;
}
希望这有帮助。
答案 4 :(得分:1)
经过几个小时的搜索和尝试,我找到了最简单的解决方案。只需将其称为“重绘”:
webView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
对于我的webview,它在scrollView中完美运行。 如果您不想使用WRAP_CONTENT,可以使用自己的参数。
答案 5 :(得分:0)
我还遇到了在通过javascript调整文本大小后WebView没有调整大小的问题。我通过将WebView的可见性设置为View.GONE直到onPageFinished()来解决这个问题。页面加载后我通过javascript调整字体大小等,setVisibility(View.VISIBLE)和WebView大小完美契合。
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);
}
});
答案 6 :(得分:0)
如果您只是删除视图然后再添加一个新视图,问题就解决了。
以下是一个例子:
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();
总而言之......它只是将新的WebView添加到同一索引处的父对象中。
答案 7 :(得分:0)
我的FrameLayout包含TextView,ProgressBar和WebView也有类似的问题。取决于服务器的返回对象我隐藏了视图,有时当我必须显示网页并在onPageFinished()中隐藏TextView和ProgressBar时,WebView有一个高度的ProgressBar。通过这段代码管理修复它:
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
new Handler().post(new Runnable() {
@Override
public void run() {
progressBar.setVisibility(View.GONE)
}
});
}
答案 8 :(得分:0)
我只将webview放在ScrollView中并设置layout_height = wrap_content并且它有效。
<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>
在我的活动中
wvQuestion = (WebView) findViewById(R.id.question_content);
wvQuestion.loadUrl(url);
答案 9 :(得分:0)
您可以根据javascript体高定期更新WebView高度,如下所示:
$(".leftboxid_"+leftboxid).on("click", function(){
var setID = $(this).attr("data-leftbox");
$(".append-left-id").val($(".append-left-id").val()+"|"+setID);
});
layout.xml:
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();
}
});
}
}
}
}
P.S。检查Android 5,4.1,4.04
答案 10 :(得分:0)
同意@Fernwilter。但改变顺序对我有用。
mWebView.setVisibility(View.GONE);
mWebView.reload();
mWebView.setVisibility(View.VISIBLE);
mWebView.loadData(".....");
答案 11 :(得分:0)
对我有用。
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);
});
}
}
});
答案 12 :(得分:-1)
有点复杂但工作......
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);
}
答案 13 :(得分:-1)
更简单的解决方案是在加载完成后使webview无效:
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(final WebView view, final String url) {
super.onPageFinished(view, url);
webView.invalidate();
}
});