Почему Android WebView отказывается от ввода данных пользователем?
Я разрабатываю приложение для Android, которое использует WebView для отображения страницы входа в Facebook. Страница загружается красиво, и я могу выбрать текстовые поля для имени пользователя / пароля, но ввод их не будет работать. То есть они определенно имеют фокус ввода (у них оранжевое поле выделения фокуса и мигающий курсор), но ввод их абсолютно ничего не делает. Я не уверен, но я думаю, что, возможно, кнопки формы также работают - они, кажется, просто обновляют страницу, а не отправляют форму.
Просто чтобы прояснить, хотя я особенно заинтересован в том, чтобы запустить Facebook, я уверен, что это не проблема Facebook, поскольку другие сайты (Google и т. Д.) Также демонстрируют такое же поведение.
У кого-нибудь есть идеи, в чем может быть проблема?
17 ответов
Оказывается, что, по-видимому, проблема заключалась в том, что WebView не имел фокуса.
Я обнаружил, что использование клавиш со стрелками для фокусировки на текстовых полях заставляет их работать, поэтому я предположил, что где-то возникла проблема с чем-то, что не имеет фокуса, скорее всего, WebView не имеет фокуса. Конечно, добавление следующей строки, похоже, решило проблему:
webView.requestFocus(View.FOCUS_DOWN);
Я все еще затрудняюсь объяснить, почему именно проблема возникла в первую очередь - текстовые поля должны работать независимо от того, получают ли они фокус от прикосновения к ним или от того, что на них указывают "стрелки", - но, по крайней мере, у меня есть решение, которое, кажется, работает,
Спасибо за ваш вклад wf.
@Mac делает эту единственную строку:
webView.requestFocus(View.FOCUS_DOWN);
решил вашу проблему? Я не в моем случае, но это делает:
mWebView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
if (!v.hasFocus()) {
v.requestFocus();
}
break;
}
return false;
}
});
только для вашей ссылки.
Это наиболее
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setUseWideViewPort(true);
webview.requestFocus(View.FOCUS_DOWN);
и если все еще не работает, то используйте одну альтернативу ниже
Альтернатива 1
webview.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
if (!v.hasFocus()) {
v.requestFocus();
}
break;
}
return false;
}
});
Альтернатива 2
webview.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
v.requestFocusFromTouch();
break;
}
return false;
}
});
Я не знаю, что мой случай точно такой же, как ваш,
Я обнаружил, что добавить одну строку CSS может решить проблему.
Я просто добавляю
input{
-webkit-user-select: text;
}
к моему css, то проблема решена!
Мне жаль говорить, что ничего из этого не помогло мне. Я думаю, это зависит от вашего контекста. В моем случае проблема возникла во всплывающем окне html (абсолютный div). Все остальные поля ввода были в порядке.
Разбивая проблему, я обнаружил, что это ошибка в веб-обзоре. Фиксированные позиционные элементы div, содержащие другие фиксированные / абсолютные позиции div, прерывают поля ввода на странице. Отсюда и правило, которое я сформулировал для вас (не стесняйтесь переформулировать):
Если на вашей странице у вас есть фиксированный позиционный div с позиционированными вложенными div ами по умолчанию (т. Е. Абсолютный, фиксированный и т. Д.), Любой из следующих абсолютных позиционированных div на вашей странице, содержащий поля ввода, получит неожиданное поведение.
Поэтому поместите поля ввода вверху страницы (если можете) или избегайте абсолютных делителей, вложенных в другие фиксированные / абсолютные деления. Это должно помочь.
Я написал что-то об этом в своем блоге, если вам нужны дополнительные объяснения и возможные обходные пути: http://java-cerise.blogspot.com/2012/02/android-web-view-inputfields-refuse-to.html
В моем случае TabHost
из предыдущего фрагмента в заднем стеке крадут фокус от ввода WebView при каждом нажатии клавиши. Вот как я это исправил:
tabHost.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
@Override
public void onViewDetachedFromWindow(View v) {}
@Override
public void onViewAttachedToWindow(View v) {
tabHost.getViewTreeObserver().removeOnTouchModeChangeListener(tabHost);
}
});
См. https://code.google.com/p/android/issues/detail?id=2516 дополнительную информацию по этой теме.
Я попробовал все другие решения, опубликованные здесь, ни одно из которых не сработало.
Вместо этого я расширил WebView и переопределил InputConnection, что заставило KeyEvents выполнить диспетчеризацию.
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
return new BaseInputConnection(this, false);
}
Не уверен, что это проблема, поскольку другие веб-сайты также показывают то же поведение, но вы включили JavaScript? WebView не включает его по умолчанию.
WebView webView = (WebView)findViewById(R.id.yourWebView);
webView.getSettings().setJavaScriptEnabled(true);
Я трачу много времени на решение этой проблемы. Наконец, я понял, что речь идет не о WebView. В моем случае, у меня есть веб-просмотр внутри диалога. Я хочу обработать обратно нажатую кнопку, чтобы отменить диалог и завершить деятельность. И я написал код ниже:
private void setOnBackPressed() {
this.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
dialog.dismiss();
activity.finish();
}
return true;
}
});
}
Поэтому, когда я использую клавиатуру, этот метод как-то отклоняет все нажатия клавиш, и тогда он не появляется в текстовых полях.
Я только изменил возвращаемое значение на ложь. Итак, это сработало правильно.
Надеюсь, поможет!!
PS: этот метод находится внутри моего диалогового класса, который расширяет класс Dialog
Это случилось со мной при загрузке страницы в 4.1.2 и 4.2.2, и после одного дня поиска я нашел ответ здесь (комментарий № 18)
Цитата из оригинального сообщения:
Некоторые из различных веб-страниц, с которыми я рендерил WebView
не вписался в WebView
и в результате div (или некоторый другой html-компонент) незаметно накладывался на поля ввода. Хотя поля ввода казались выделенными при прикосновении, они не позволяли вводить текст (даже если бы мне удалось поднять экранную клавиатуру с помощью трекбола).
Итак, решение.
webview.getSettings().setUseWideViewPort(true);
Это не полностью остановит проблему, но сделает вид больше похожим на браузер ПК, для которого предназначены сайты. Меньше смена оверлея.
Я столкнулся с этой проблемой, потому что я показываю заставку, когда веб-просмотр загружает первую страницу. Я устанавливаю для веб-просмотра значение View.VISIBLE в onPageFinished, однако, несмотря на возможность фокусировки текстовых полей, вы не можете в них вводить. Я также могу подтвердить, что исправление, устанавливающее запрос viewFocus webView в View.FOCUS_DOWN, работает.
NB. Если в onResume я установил для веб-просмотра View.VISIBLE, проблема не возникнет, но в моем случае заставка исчезнет слишком рано.
По умолчанию в Android Webview разрешает ввод данных пользователем с базовыми конфигурациями: -
android:focusable="true"
android:focusableInTouchMode="true"
& включил JavaScript, но убедитесь, что нет блокировки фокусируемости на уровне активности / фрагмента , в моем случае
android:descendantFocusability="blocksDescendants"
просто удалил это, работал у меня. Поэтому перепроверьте такие случаи и исправьте их соответствующим образом.
Я нашел проблему, которая может отличаться, но она звучит похоже. В родном браузере Android 2.3, если у вас есть фиксированные позиции элементов на странице, он иногда ломает поля выбора.
Обходной путь для этой проблемы для устройств 2.3 - никогда не допускать пустых дочерних элементов для родительского элемента с фиксированной позицией. Таким образом,
<div style="position:fixed">
<div>
<span>not empty</span>
<span></span>
</div>
</div>
станет
<div style="position:fixed">
<div>
<span>not empty</span>
<span> </span>
</div>
</div>
Это исправило мою проблему.
Не знаю, была ли это проблема вашей проблемы, и это спустя год после этого, но я подумала, что поделюсь этим, поскольку в настоящее время я имею дело с еще одной проблемой фиксированного положения в приложении, и у меня нет не нашел обходного пути для этого.
Я столкнулся с подобной проблемой, что текстовые вводы не работают на веб-просмотре. Когда вы сосредотачиваетесь на вводе текста, он показывает клавиатуру, но вы не можете вводить какие-либо символы.
После долгих поисков решения я обнаружил, что это решает проблему:
body {
-webkit-transform: translate3d(0,0,0);
-moz-transform: translate3d(0,0,0);
-ms-transform: translate3d(0,0,0);
-o-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
Как я понял, это правило заставляет некоторые устройства запускать аппаратное ускорение. Больше информации о translate3d(0,0,0) здесь.
С другой стороны, согласно этой статье не рекомендуется везде использовать ускорение GPU.
В моем контексте (веб-просмотр, содержащий внешний URL), этот фрагмент работает:
webview.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
v.requestFocusFromTouch();
break;
}
return false;
}
});
ошибка в том, что при каждом прикосновении веб-представление теряло фокус!
Если мы имеем дело с EditText
в WebView
, затем v.requestFocusFromTouch ()
не будет работать, если мы должны USER_AGENT
написанный Mozilla / 5.0 (X11; Linux i686) и будет нормально работать, если Mozilla / 5.0 (X11; Linux x86_64).
Это также произошло в моем проекте. Я перепробовал все вышеперечисленные методы, ни один из них не может быть эффективным. Наконец, я решил эту проблему с помощью темы диалога, заменившей родной диалог. Надеюсь, что это может помочь кому-то!