У меня есть приложение, которое в значительной степени зависит от WebView. После обновления KitKat пользователи сообщают, что приложение не обновляет текст после увеличения или уменьшения масштаба. Я просмотрел документацию и увидел, что многое изменилось, но в то время, когда он много говорит о масштабировании и масштабировании, ничего не говорится о перепланировке текста. Кажется, что, когда установлен режим просмотра, масштабирование - это объект панорамирования и масштабирования, и теперь нет возможности обновить текст после масштабирования. Есть ли какое-нибудь решение?Нет текста Reflow после увеличения KitKat WebView
ответ
KitKat Chromium WebView не переплачивает текст. Если вас беспокоит текстовая разборчивость, см. Раздел «NARROW_COLUMNS и SINGLE_COLUMN больше не поддерживается» в migration guide, где предлагаемое решение заключается в использовании автосохранения текста.
Если вы действительно хотите, чтобы довести этот эффект тогда вам нужно сделать что-то вроде этого:
- Поместите все содержимое в
<div id="contentRoot"> </div>
Реализовать 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());
Использовать следующие JavaScript
function recalculateWidth() { $("#contentRoot").width(window.innerWidth); }
или, альтернативно, вы можете попробовать изменить метатег viewport.
выше следует выполнить оплавление с небольшой задержкой (что там, чтобы сохранить количество ненужных повторных раскладок до минимума).
Спасибо, всем, за эту замечательную нить !! Я хочу добавить свои 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';");
Я не знаю, почему, но с добавлением «точек» было важно для меня.
он оставляет много лишнего места в крайнем правом углу, а также window.innerWidth уменьшается по мере увеличения –
Спасибо за эти подсказки - объединяющие их, я нашел следующий обходной путь не нуждаясь 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(); });
К сожалению , кажется, что события с фиксированным зумом не могут быть пойманы.
Это старая тема, но я просто хотел добавить решение, которое я использую, в случае, если кто-то может извлечь из этого выгоду. Я столкнулся с проблемой странной масштабирования на некоторых страницах при увеличении масштаба до конца, и, к сожалению, ее трудно обнаружить в 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, решения которого я объединил и модифицирована, чтобы построить этот ответ.
, почему он оставляет дополнительное пространство справа от веб-представления. –
Какая часть работает только на версиях выше Kitkat? – nilsi
@ nilsi ниже KitKat, WebView поддерживает масштабирование текста изначально, поэтому в идеале вы не захотите использовать этот хак в версиях под ним. – anthonycr
Этот код будет убедиться, чтобы решить вашу проблему 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);
}
@EladAvron I просто попробовал это быстро и отлично работает для меня '' 'document.getElementById ('contentRoot'). style.width = window.innerWidth;' '' является точным J S Я использовал, и я вызвал JS непосредственно из '' 'onScaleChanged'''. Может быть, использовать DevTools, чтобы узнать, называется ли JavaScript? –
Спасибо, я попробую еще раз и посмотрю, как это работает. В худшем случае я получил что-то похожее на работу: viewport.setAttribute ('content', 'width = device-width, initial-scale =' + newScale + '); 'на основе вашей идеи использовать' onScaelChanged', I «Попробуй оба метода и посмотри, что я могу работать. –
Ну, что ты знаешь - теперь это сработало! Не знаю, что я сделал неправильно раньше, но это было явно что-то глупое. :-P Кроме того, будущий совет любому, кто рассматривает возможность использования масштабирования в окне просмотра, - нет, потому что тогда он будет масштабировать и масштабировать область просмотра, получая вам очень большой и необратимый видовой экран. Если вы не используете внешние элементы управления, в этом случае идите в гайки. –