it-swarm.com.ru

Как изменить размер веб-просмотра Android после добавления в него данных

В иерархической структуре (линейной, вертикальной) у меня есть несколько представлений, и одним из них является WebView . Все они имеют одинаковые параметры:

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

Для всех представлений интервал между элементами корректно обрабатывается, но для веб-просмотра много места после отображаемого текста внутри.

Я установил (HTML) текст веб-просмотра в методе «onCreate» упражнения, используя макет.

Есть ли способ, позволяющий веб-представлению изменить размер, чтобы соответствовать его размеру контента? 

Кстати, оставшееся пространство варьируется от одного устройства к другому (эмулятор против Milestone против Hero)

Любая идея? Спасибо

15
user240051

Я уверен, что это слишком поздно, но добавляю метод, который работал для меня, если кто-то еще приходит сюда в поисках решения.

Как только страница заканчивается загрузка, я внедряю метод 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)));
        }
    });
}

Такое же решение можно увидеть здесь.

18
Chitranshu Asthana

Кажется, что в данный момент Webview изменяет свой размер только в том случае, если содержание слишком велико. Если веб-просмотр больше, то контент не сжимается, чтобы освободить место.

6
Janusz

У меня такая же проблема. Я решил, изменив видимость WebView.

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

После нескольких часов поисков и попыток я нашел самое простое рабочее решение. Просто назовите это как «перекрасить»:

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

Для моего веб-просмотра он отлично работает внутри scrollView . Если вы не хотите использовать WRAP_CONTENT, вы можете использовать свои собственные параметры.

1
eJal

Я нашел:

(1) есть две высоты в веб-просмотре. MeasureHeight и contentHeight. Обратите внимание, что contentHeight вычисляется из webcoreThread. Две высоты не согласованы в любое время!

(2) когда макет закончится. Веб-просмотр перезагрузит контент. ContentHeight согласуется с measureHeight.

Поэтому я думаю, что одно из решений заключается в следующем: сделать веб-просмотр перезагрузить контент после завершения макета.

Мое решение:

(1) расширяет веб-просмотр . (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) веб-просмотр должен быть инициализирован перед загрузкой каждого контента.

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

Надеюсь это поможет.

1
user1253661

У меня была похожая проблема с FrameLayout, содержащим TextView, ProgressBar и WebView. Зависит от объекта возврата с сервера. Я скрывал представления, а иногда, когда мне приходилось показывать веб-страницу и скрывать TextView и ProgressBar в onPageFinished (), в 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)
        }
    });
}
0
Mateusz Jablonski

Вы можете периодически обновлять высоту WebView в соответствии с высотой тела JavaScript, например так:

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>

Постскриптум Проверено на Android 5, 4.1, 4.04

0
caiiiycuk

Согласитесь с @Fernwilter. Но изменение последовательности сработало для меня.

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

Я только поместил веб-видение в 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);
0
VuVanLy

Это сработало для меня.

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

Если вы просто удалите представление, а затем добавите новое обратно, проблема решена. 

Вот пример:

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 точно так же, как старый обратно к своему родителю с тем же индексом. 

0
Codeversed

У меня также была проблема с тем, что WebView не подходит под размер после настройки размера текста с помощью javascript. Я решил эту проблему, установив видимость 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); 

        }  
    });  
0
Johnny O