web-dev-qa-db-de.com

So ändern Sie die Größe einer Android-Webansicht nach dem Hinzufügen von Daten

In einer Layout-Hierarchie (linear, vertikal) habe ich mehrere Ansichten, von denen eine eine WebView ist. Sie haben alle die gleichen Parameter:

Android:layout_width="fill_parent"
Android:layout_height="wrap_content"

Bei allen Ansichten wird der Abstand zwischen Elementen korrekt behandelt, bei der Webansicht gibt es jedoch viele Leerzeichen nach dem angezeigten Text.

Ich habe den (HTML-) Text der Webansicht in der "onCreate" -Methode der Aktivität mithilfe des Layouts festgelegt.

Gibt es eine Möglichkeit, die Größe der Webansicht an die Größe des Inhalts anzupassen?

Übrigens ist der verbleibende Speicherplatz von Gerät zu Gerät unterschiedlich (Emulator vs Milestone vs Hero)

Irgendeine Idee? Vielen Dank

15
user240051

Ich bin mir sicher, dass dies zu spät ist, füge aber die Methode hinzu, die für mich funktioniert hat, falls jemand anderes hierher kommt, um nach einer Lösung zu suchen.

Sobald die Seite geladen ist, injiziere ich eine JavaScript-Methode, um mich als JS-Hook zurückzurufen. Und bei dieser Methode übergebe ich die Größe von.

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

Die gleiche Lösung ist auch zu sehen hier.

18

Momentan ändert sich die Größe der Webansicht anscheinend nur, wenn der Inhalt zu groß ist. Wenn die Webansicht größer ist, wird der Inhalt nicht verkleinert, um den Speicherplatz freizugeben.

6
Janusz

Ich hatte das gleiche problem Ich habe das Problem gelöst, indem ich die Sichtbarkeit des WebView geändert habe.

mWebView.setVisibility(View.GONE);
mWebView.loadData(".....");
mWebView.reload();
mWebView.setVisibility(View.VISIBLE);
4
Fernwilter

Nach einigen Stunden des Suchens und Versuchens fand ich die einfachste funktionierende Lösung. Nennen Sie dies einfach "neu streichen":

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

Für meine Webansicht funktioniert es perfekt in einer scrollView. Wenn Sie WRAP_CONTENT nicht verwenden möchten, können Sie Ihre eigenen Parameter verwenden.

1
eJal

Ich fand:

(1) In Webview gibt es zwei Höhen. MeasureHeight und contentHeight. Beachten Sie, dass contentHeight vom webcoreThread berechnet wird. Die beiden Höhen stimmen zu keiner Zeit überein!

(2) Wenn das Layout fertig ist. Die Webansicht lädt den Inhalt neu. Die contentHeight stimmt mit measureHeight überein.

Ich denke, eine Lösung ist: Lassen Sie Webview den Inhalt neu laden, nachdem das Layout fertig ist.

Meine Lösung:

(1) erweitert die Webansicht. (2) onlayout () überschreiben , 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 muss vor dem Laden aller Inhalte initialisiert werden.

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

Hoffe das hilft.

1
user1253661

Ich hatte ein ähnliches Problem mit FrameLayout, das TextView, ProgressBar und WebView enthielt. Abhängig vom Rückgabeobjekt vom Server habe ich Ansichten ausgeblendet und manchmal, wenn ich eine Webseite anzeigen und TextView und ProgressBar in onPageFinished () verstecken musste, hatte WebView eine Menge ProgressBar. Verwalten, um es mit diesem Code zu beheben:

public void onPageFinished(WebView view, String url) {
    super.onPageFinished(view, url);
    new Handler().post(new Runnable() {
        @Override
        public void run() {
            progressBar.setVisibility(View.GONE)
        }
    });
}
0

Sie können die WebView-Größe in regelmäßigen Abständen entsprechend der Körpergröße von Javascript aktualisieren:

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. Überprüft auf Android 5, 4.1, 4.04

0
caiiiycuk

Zustimmen mit @Fernwilter. Aber die Reihenfolge zu ändern hat bei mir funktioniert.

mWebView.setVisibility(View.GONE);
mWebView.reload();
mWebView.setVisibility(View.VISIBLE);
mWebView.loadData(".....");
0
NameNotFound

Ich habe nur die Webansicht in die ScrollView eingefügt und layout_height = wrap_content gesetzt, und es hat funktioniert.

<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>

Und in meiner Tätigkeit

wvQuestion = (WebView) findViewById(R.id.question_content);
wvQuestion.loadUrl(url);
0
VuVanLy

Es hat bei mir funktioniert.

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

                    });
                }
            }
        });
0
Tuan Nguyen

Wenn Sie einfach die Ansicht entfernen und dann eine neue hinzufügen, ist das Problem behoben.

Hier ist ein Beispiel:

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

Fazit: Es wird nur eine neue WebView wie die alte direkt an den übergeordneten Index an derselben Stelle angehängt.

0
Codeversed

Ich hatte auch das Problem, dass die Größe des WebView nach der Anpassung der Textgröße über Javascript nicht angepasst werden konnte. Ich habe dieses Problem gelöst, indem ich die Sichtbarkeit des WebView auf View.GONE bis onPageFinished () gesetzt habe. Nachdem die Seite geladen wurde, ändere ich die Schriftgröße usw. über Javascript, setVisibility (View.VISIBLE) und die WebView-Größen so, dass sie perfekt passen.

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

        }  
    });  
0
Johnny O