web-dev-qa-db-fra.com

Comment redimensionner une vue Web Android après y avoir ajouté des données

Dans une hiérarchie de présentation (linéaire, verticale), j'ai plusieurs vues et l'une d'entre elles est une vue Web. Ils ont tous les mêmes paramètres:

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

L'espacement entre les éléments est correctement géré pour toutes les vues, mais pour la vue Web, il y a beaucoup d'espaces après le texte affiché.

J'ai défini le texte (HTML) de la vue Web dans la méthode "onCreate" de l'activité à l'aide de la mise en page.

Existe-t-il un moyen de laisser la vue Web se redimensionner de manière à correspondre à la taille de son contenu?

À propos, l’espace disponible varie d’un appareil à l’autre (émulateur vs Milestone vs Hero)

Une idée? Merci

15
user240051

Je suis sûr que c'est trop tard, mais en ajoutant la méthode qui a fonctionné pour moi au cas où quelqu'un d'autre viendrait ici chercher une solution.

Une fois le chargement de la page terminé, j'injecte une méthode javascript pour me rappeler le crochet JS. Et dans cette méthode, je passe la taille de.

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

La même solution peut également être vu ici.

18
Chitranshu Asthana

Il semble qu’à l’heure actuelle, Webview ne se redimensionne que si le contenu est trop volumineux. Si la vue Web est plus grande, le contenu ne sera pas réduit pour récupérer de l'espace.

6
Janusz

J'ai eu le même problème. J'ai résolu en changeant la visibilité de la WebView.

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

Après quelques heures de recherche et d’essai, j’ai trouvé la solution de travail la plus simple. Appelez ça simplement "repeindre":

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

Pour ma vue Web, cela fonctionne parfaitement dans un scrollView. Si vous ne souhaitez pas utiliser WRAP_CONTENT, vous pouvez utiliser vos propres paramètres.

1
eJal

J'ai trouvé:

(1) il y a deux hauteurs dans la vue Web. MeasureHeight et contentHeight. Notez que le contentHeight est calculé à partir du webcoreThread. Les deux hauteur ne sont pas compatibles à tout moment!

(2) à la fin de la mise en page, la visualisation Web recharge le contenu. Le contenuHauteur est compatible avec mesureHauteur.

Je pense donc qu’une solution est la suivante: faire en sorte que Webview recharge le contenu une fois la mise en page terminée.

Ma solution:

(1) étend la vue Web. (2) remplace 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 need init avant de charger chaque contenu.

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

J'espère que cela t'aides.

1
user1253661

J'ai eu un problème similaire avec FrameLayout contenant TextView, ProgressBar et WebView. Dépend de l'objet de retour du serveur, je masquais des vues et parfois, lorsque je devais afficher une page Web et masquer TextView et ProgressBar dans onPageFinished () WebView comportait un nombre élevé de ProgressBar. Gérez le réparer avec ce morceau de code:

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

Vous pouvez périodiquement mettre à jour la hauteur de la vue Web en fonction de la hauteur du corps javascript, comme suit:

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. Vérifié sur Android 5, 4.1, 4.04

0
caiiiycuk

D'accord avec @Fernwilter. Mais changer la séquence a fonctionné pour moi.

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

J'ai seulement placé la vue Web à l'intérieur de ScrollView et mis layout_height = wrap_content et cela a fonctionné.

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

Et dans mon activité

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

Cela a fonctionné pour moi.

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

Si vous supprimez simplement la vue puis ajoutez une nouvelle, le problème est résolu.

Voici un exemple:

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

En résumé ... il ajoute simplement une nouvelle WebView, comme l’ancienne version précédente, à son parent au même index.

0
Codeversed

J'ai également eu le problème de la taille de la WebView à s'adapter après ajustement de la taille du texte via javascript. J'ai résolu ce problème en définissant la visibilité de WebView sur View.GONE jusqu'à ce que onPageFinished (). Une fois la page chargée et j’ai modifié la taille de la police, etc. via javascript, définissez Visibilité (View.VISIBLE) et la taille de la vue Web pour s’adapter parfaitement.

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