23

在布局(线性、垂直)层次结构中,我有几个视图,其中一个是 WebView。它们都有相同的参数:

android:layout_width="fill_parent"
android:layout_height="wrap_content"

对于所有视图,元素之间的间距都得到了正确处理,但对于 Webview,在里面显示的文本之后有很多空格。

我使用布局在活动的“onCreate”方法中设置了 webview 的(HTML)文本。

有没有办法让 webview 自行调整大小以匹配其内容大小?

顺便说一句,剩余空间因设备而异(模拟器 vs Milestone vs Hero)

任何想法?谢谢

4

14 回答 14

25

我确信这为时已晚,但添加对我有用的方法,以防其他人来这里寻找解决方案。

页面完成加载后,我将注入一个 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)));
        }
    });
}

在这里也可以看到相同的解决方案

于 2014-08-07T16:00:08.193 回答
7

目前看来,如果内容太大,Webview 只会自行调整大小。如果 webview 更大,那么它不会缩小以回收空间的内容。

于 2010-05-06T10:11:24.050 回答
6

我有同样的问题。我通过更改 WebView 的可见性来解决。

mWebView.setVisibility(View.GONE);
mWebView.loadData(".....");
mWebView.reload();
mWebView.setVisibility(View.VISIBLE);
于 2012-03-27T06:52:43.230 回答
5

经过几个小时的搜索和尝试,我找到了最简单的工作解决方案。只需将其称为“重绘”:

webView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

对于我的 webview,它在 scrollView 中完美运行。如果您不想使用 WRAP_CONTENT,可以使用自己的参数。

于 2015-11-10T23:22:40.480 回答
4

我只将 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);
于 2015-04-26T04:46:33.107 回答
1

我发现:

(1) webview中有两个高度。MeasureHeight 和 contentHeight。请注意,contentHeight 是从 webcoreThread 计算的。两人的身高随时都不一致!

(2) 当布局完成时,webview 重新加载内容。contentHeight 与 measureHeight 一致。

所以我认为一种解决方案是:在布局完成后让 webview 重新加载内容。

我的解决方案:

(1) 扩展 webview 。(2)覆盖onlayout(),dispatchDraw(),</p>

@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 在加载每个内容之前需要初始化。

public void intiFlag() {
    mchanged = true;
        finished = false ;
}

希望这可以帮助。

于 2012-03-07T02:45:26.187 回答
1

您可以根据 javascript body 高度定期更新 WebView 高度,如下所示:

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();
                    }
                });
            }
        }
    }
}

布局.xml:

<WrapContentWebView
            android:layout_width="match_parent"
            android:layout_height="0dp">
</WrapContentWebView>

PS 在 Android 5、4.1、4.04 上检查

于 2016-05-16T11:24:48.913 回答
0

我对包含 TextView、ProgressBar 和 WebView 的 FrameLayout 也有类似的问题。取决于来自服务器的返回对象,我隐藏了视图,有时当我不得不显示网页并在 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)
        }
    });
}
于 2014-06-17T09:00:40.480 回答
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 添加到其父项中,就像旧的权利一样。

于 2013-11-21T07:12:30.227 回答
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); 

        }  
    });  
于 2012-10-10T06:49:48.050 回答
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);

                    });
                }
            }
        });
于 2018-09-12T08:44:20.127 回答
0

同意@Fernwilter。但是改变顺序对我有用。

mWebView.setVisibility(View.GONE);
mWebView.reload();
mWebView.setVisibility(View.VISIBLE);
mWebView.loadData(".....");
于 2017-01-27T08:32:31.747 回答
-1

一个更简单的解决方案是在加载完成后使 webview 无效:

  webView.setWebViewClient(new WebViewClient() {

            @Override
            public void onPageFinished(final WebView view, final String url) {
                super.onPageFinished(view, url);
                webView.invalidate();
            }
        });
于 2013-01-07T15:38:55.727 回答
-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);
}
于 2010-12-02T11:28:01.840 回答