Почему 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>&nbsp;</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).

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

Другие вопросы по тегам