3

У меня есть приложение, которое в значительной степени зависит от WebView. После обновления KitKat пользователи сообщают, что приложение не обновляет текст после увеличения или уменьшения масштаба. Я просмотрел документацию и увидел, что многое изменилось, но в то время, когда он много говорит о масштабировании и масштабировании, ничего не говорится о перепланировке текста. Кажется, что, когда установлен режим просмотра, масштабирование - это объект панорамирования и масштабирования, и теперь нет возможности обновить текст после масштабирования. Есть ли какое-нибудь решение?Нет текста Reflow после увеличения KitKat WebView

ответ

10

KitKat Chromium WebView не переплачивает текст. Если вас беспокоит текстовая разборчивость, см. Раздел «NARROW_COLUMNS и SINGLE_COLUMN больше не поддерживается» в migration guide, где предлагаемое решение заключается в использовании автосохранения текста.

Если вы действительно хотите, чтобы довести этот эффект тогда вам нужно сделать что-то вроде этого:

  1. Поместите все содержимое в <div id="contentRoot"> </div>
  2. Реализовать onScaleChanged

    class MyWebViewClient extends WebViewClient { 
        boolean scaleChangedRunnablePending = false; 
    
        // Other code here 
    
        @Override 
        void onScaleChanged(final WebView webView, fload oldScale, float newScale) { 
         if (scaleChangedRunnablePending) return; 
         view.postDelayed(new Runnable() { 
          @Override 
          public void run() { 
           webView.evaluateJavaScript("recalculateWidth();", null); 
           scaleChangedRunnablePending = false; 
          } 
         }, 100); 
        } 
    } 
    
    // Don't forget to webView.setWebViewClient(new MyWebViewClient()); 
    
  3. Использовать следующие JavaScript

    function recalculateWidth() { 
        $("#contentRoot").width(window.innerWidth); 
    } 
    

    или, альтернативно, вы можете попробовать изменить метатег viewport.

выше следует выполнить оплавление с небольшой задержкой (что там, чтобы сохранить количество ненужных повторных раскладок до минимума).

+3

@EladAvron I просто попробовал это быстро и отлично работает для меня '' 'document.getElementById ('contentRoot'). style.width = window.innerWidth;' '' является точным J S Я использовал, и я вызвал JS непосредственно из '' 'onScaleChanged'''. Может быть, использовать DevTools, чтобы узнать, называется ли JavaScript? –

+0

Спасибо, я попробую еще раз и посмотрю, как это работает. В худшем случае я получил что-то похожее на работу: viewport.setAttribute ('content', 'width = device-width, initial-scale =' + newScale + '); 'на основе вашей идеи использовать' onScaelChanged', I «Попробуй оба метода и посмотри, что я могу работать. –

+0

Ну, что ты знаешь - теперь это сработало! Не знаю, что я сделал неправильно раньше, но это было явно что-то глупое. :-P Кроме того, будущий совет любому, кто рассматривает возможность использования масштабирования в окне просмотра, - нет, потому что тогда он будет масштабировать и масштабировать область просмотра, получая вам очень большой и необратимый видовой экран. Если вы не используете внешние элементы управления, в этом случае идите в гайки. –

5

Спасибо, всем, за эту замечательную нить !! Я хочу добавить свои 2cents. Нет необходимости добавлять дополнительный div с id = 'contentRoot' в файл HTML. Вы можете использовать тег body, который должен уже существовать в любом html. Кроме того, как писал EladAvron, JS-код можно напрямую вызывать из Java. В целом, оригинальный ответ, который опубликовал marcin.kosiba, применим к HTML, который вы не имеете права изменять.

Вызов JS, который работал для меня:

webview.loadUrl("javascript:document.getElementsByTagName('body')[0].style.width=window.innerWidth+'px';"); 

Я не знаю, почему, но с добавлением «точек» было важно для меня.

+0

он оставляет много лишнего места в крайнем правом углу, а также window.innerWidth уменьшается по мере увеличения –

1

Спасибо за эти подсказки - объединяющие их, я нашел следующий обходной путь не нуждаясь Java:

var innerWidth = 0; 
var text_reflow = function() { 
    if (window.innerWidth != innerWidth) { 
    innerWidth = window.innerWidth; 
    document.getElementsByTagName('body')[0].style.width = innerWidth+'px'; 
    } 
}; 
text_reflow(); 
setInterval(text_reflow, 500); 

Вместо того, чтобы использовать интервал опроса, можно сделать, например, также

window.onresize = text_reflow; 
addListener(window, 'touchstart', function (e) { text_reflow(); }); 

К сожалению , кажется, что события с фиксированным зумом не могут быть пойманы.

1

Это старая тема, но я просто хотел добавить решение, которое я использую, в случае, если кто-то может извлечь из этого выгоду. Я столкнулся с проблемой странной масштабирования на некоторых страницах при увеличении масштаба до конца, и, к сожалению, ее трудно обнаружить в JavaScript, если страница будет увеличена на весь экран. Решение этого заключается в том, чтобы определить, достаточно ли масштаб изменения масштаба, прежде чем изменять размер страницы.

Следующее решение работает на KitKat и Lollipop, а не имеет досадного постепенного уменьшения масштаба, который я видел на некоторых веб-сайтах.

class MyWebViewClient extends WebViewClient { 
    private boolean mIsRunning = false; 
    private float mZoomScale = 0.0f; 
    private static final String REFLOW_TEXT = "javascript:document.getElementsByTagName('body')[0].style.width=window.innerWidth+'px';" 

    @Override 
    public void onScaleChanged(final WebView view, final float oldScale, final float newScale) { 
     if (view.isShown() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
      if (mIsRunning) // Don't run if there's a resize runnable in the queue 
       return; 
      if (Math.abs(mZoomScale - newScale) > 0.01f) { // This stops the gradual zoom 
       mIsRunning = view.postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         mZoomScale = newScale; 
         view.evaluateJavascript(REFLOW_TEXT, null); 
         mIsRunning = false; 
        } 
       }, 100); 
      } 
     } 
    } 
} 

Благодаря marcin.kosiba и user3185518, решения которого я объединил и модифицирована, чтобы построить этот ответ.

+0

, почему он оставляет дополнительное пространство справа от веб-представления. –

+0

Какая часть работает только на версиях выше Kitkat? – nilsi

+0

@ nilsi ниже KitKat, WebView поддерживает масштабирование текста изначально, поэтому в идеале вы не захотите использовать этот хак в версиях под ним. – anthonycr

0

Этот код будет убедиться, чтобы решить вашу проблему 100% Проблема с KitKat Поставляется в виде тонкой головы

<meta name="viewport" content="maximum-scale=0"> java> view.evaluateJavascript("document.getElementsByTagName('head')[0].appendChild('<meta name=\"viewport\" content=\"maximum-scale=0\">');", null);

webView.setWebViewClient(new WebViewClient() { 
      boolean scaleChangedRunnablePending = false; 
      @Override 
      public void onScaleChanged(final WebView view, float oldScale, float newScale) { 
       super.onScaleChanged(view, oldScale, newScale); 
       if (scaleChangedRunnablePending) return; 
       view.postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         view.evaluateJavascript("document.getElementsByTagName('head')[0].appendChild('<meta name=\"viewport\" content=\"maximum-scale=0\">');", null); 
         scaleChangedRunnablePending = false; 
        } 
       }, 100); 
      } 
Смежные вопросы