Как изменить размер веб-представления android после добавления в него данных
В иерархии макета (линейная, вертикальная) у меня есть несколько видов, и один из них - WebView.
Все они имеют одинаковые параметры:
android:layout_width="fill_parent"
android:layout_height="wrap_content"
Для всех представлений расстояние между элементами корректно обрабатывается, но для Web-просмотра существует много пробелов после отображаемого текста внутри.
Я установил (html) текст веб-представления в методе "onCreate" активности, используя макет.
Можно ли изменить размер веб-представления, чтобы соответствовать размеру содержимого?
Кстати, оставшееся пространство меняется от одного устройства к другому (эмулятор против Milestone vs Hero)
Любая идея? Благодаря
Ответы
Ответ 1
Я уверен, что это слишком поздно, но добавление метода, который работал у меня, в случае, если кто-то еще приходит сюда искать решение.
Как только страница заканчивает загрузку, я ввожу 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)));
}
});
}
То же самое решение можно увидеть здесь.
Ответ 2
Похоже, что на данный момент Webview только изменяет размеры, если содержимое слишком велико. Если веб-просмотр больше, чем контент, который он не сжимает, чтобы вернуть пространство.
Ответ 3
У меня была та же проблема. Я решил, изменив видимость WebView.
mWebView.setVisibility(View.GONE);
mWebView.loadData(".....");
mWebView.reload();
mWebView.setVisibility(View.VISIBLE);
Ответ 4
Я нашел:
(1) в веб-просмотре есть две высоты. MeasureHeight и contentHeight. Обратите внимание, что contentHeight вычисляется из webcoreThread. Две высоты не соответствуют друг другу!
(2), когда макет завершает. webview перезагружает контент. ContentHeight согласуется с measureHeight.
Итак, я думаю, что одно из решений: make 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 нужно инициализировать перед загрузкой каждого содержимого.
public void intiFlag() {
mchanged = true;
finished = false ;
}
Надеюсь, что это поможет.
Ответ 5
После нескольких часов поиска и попытки я нашел простейшее рабочее решение. Просто назовите это как "перекрасить":
webView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
Для моего веб-представления он отлично работает внутри scrollView.
Если вы не хотите использовать WRAP_CONTENT, вы можете использовать свои собственные параметры.
Ответ 6
У меня также возникла проблема с настройкой размера 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);
}
});
Ответ 7
Более простым решением является аннулирование webview после завершения загрузки:
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(final WebView view, final String url) {
super.onPageFinished(view, url);
webView.invalidate();
}
});
Ответ 8
Если вы просто удалите представление, а затем добавите новый, проблема будет решена.
Вот пример:
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, как старый, обратно к своему родительскому объекту в том же индексе.
Ответ 9
У меня была аналогичная проблема с 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)
}
});
}
Ответ 10
Я только поместил 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);
Ответ 11
Вы можете периодически обновлять высоту 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>
P.S. Проверено на Android 5, 4.1, 4.04
Ответ 12
Согласитесь с @Fernwilter. Но изменение последовательности сработало для меня.
mWebView.setVisibility(View.GONE);
mWebView.reload();
mWebView.setVisibility(View.VISIBLE);
mWebView.loadData(".....");
Ответ 13
Немного сложно, но работает...
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);
}