Android WebView - настройка фокуса фокуса HTML с использованием Javascript

У меня есть приложение только с видимым WebView компонентом, который используется для отображения некоторого динамически сгенерированного HTML (также можно запустить Javascript). Он активирован для WebView.

На нескольких страницах я пытаюсь установить фокус одного из входных текстовых полей после завершения загрузки страницы - не через Тело onLoad(), а вместо этого с помощью вызова JS после страница закончила загрузку, т.е. в onPageFinished(). Большая часть javascript выполняет тонкие

    webview.loadURL("javascript:JSMethod();");

Но когда я использую один и тот же вызов для выполнения document.getElementById('text1').focus() - курсор достигает элемента, но Soft Keyboard не выскочит. Тот же код javascript, который выполняется с помощью кнопки на странице, имеет желаемый эффект.

Я добавляю исходный код, который имеет 3 кнопки

  • Focus Text1 - Поместите курсор на текст1 и всплывает Softkeyboard.
  • Java Focus Text1 - вызывает Java для выполнения того же JS. Отображает только курсор и не выталкивает клавиатуру.
  • Java Focus Text1 And Keyboard Open - Вызывает JS из Java и Force Keyboard open.

Я понимаю, что выполнение JS должно работать одинаково, независимо от того, выполняется ли оно из браузера с помощью кнопки/события или как отправлено с Java через WebView.loadURL().

Здесь мои Запросы

  • Мне что-то не хватает при использовании Button#2? Это как мой текущий код, и я вижу только, что курсор установлен, но SoftKeyboard не открывается.
  • Когда я использую логику, написанную в Button#3, я несколько раз не вижу курсора в поле, но дает мне желаемый эффект, и курсор становится видимым, когда я набираю что-то на всплывающей клавиатуре.
  • Может ли поведение, которое я вижу в Button#2, быть ошибкой в ​​исполнении Android JS? Или может быть, что в WebView нет фокуса, почему отображается только курсор? Я также пробовал webview.requestFocus() - я не могу написать requestFocusOnTouch(), поскольку он является единственным View I, и я ожидаю, что он сфокусирован автоматически.

Код Java, демонстрирующий поведение

    import android.app.Activity;
    import android.content.Context;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.inputmethod.InputMethodManager;
    import android.webkit.JsResult;
    import android.webkit.WebChromeClient;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;

    public class WebViewProjectTestJSHTMLFocusActivity extends Activity {

        Activity _current = null;
        WebView wv = null;

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            _current = this;
            //setContentView(R.layout.main);
            String data = "<html><body>" +
                                "<script>function focusser() { document.getElementById(\"text1\").focus(); } </script>" +
                                "<script>function javaFocusser() { javautil.javaFocus(false); } </script>" +
                                "<script>function javaFocusserKeyboard() { javautil.javaFocus(true); } </script>" +
                                "Text 1<input type='text' id='text1'/><br/>" +
                                "Text 2<input type='text' id='text2'/><br/>" +
                                "<input type='button' value='Focus Text1' onClick='focusser()'/>" +
                                "<input type='button' value='Java Focus Text1' onClick='javaFocusser()'/>" +
                                "<input type='button' value='Java Focus Text1 And Keyboard Open' onClick='javaFocusserKeyboard()'/>" +
                            "</body></html>";
            wv = new WebView(this);
            wv.getSettings().setJavaScriptEnabled(true);

            // Set some HTML 
            wv.loadDataWithBaseURL("file:///android_asset/", data, "text/html", "UTF-8", null);

            // Call back required after page load finished
            wv.setWebViewClient(new CustomWebViewClient());

            // Enable Alert calls  
            wv.setWebChromeClient(new CustomWebChromeClient());

            // For JS->Java calls
            wv.addJavascriptInterface(this, "javautil");

            setContentView(wv);
        }


        /**
         * Calls the same javascript and forces the keyboard to open 
         */
        public void javaFocus(final boolean shouldForceOpenKeyboard) {

            Thread t = new Thread("Java focusser thread") {
                public void run() {
                    wv.loadUrl("javascript:focusser();");
                    if(shouldForceOpenKeyboard) {
                        InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                        mgr.showSoftInput(wv, InputMethodManager.SHOW_IMPLICIT);
                    }
                }
            };

            // Run on the View Thread.
            _current.runOnUiThread(t);
        }

        /**
         * Calls focus method after the page load is complete.
         */
        final class CustomWebViewClient
        extends WebViewClient {
            @Override
            public void onPageFinished(WebView view, String url) {
                // javaFocus(true);
                Log.d("TestExamples", "focusser call complete");
            }
        }

        final class CustomWebChromeClient
        extends WebChromeClient {
            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                Log.d("TestExamples", "JS Alert :: " + message);
                return false;
            }
        }
    }

Обновление решения 24-06-2011 Чтобы выполнить эту работу, вам нужно использовать wv.requestFocus(View.FOCUS_DOWN) непосредственно перед фактическим вызовом фокуса JS. Я изменил метод javaFocus() выше на правильную версию ниже. Раньше, когда я упоминал, что я использовал requestFocus(), я использовал это, когда WebView был инициализирован в методе onCreate(). Основное различие заключается в том, что теперь мы заставляем WebView получать фокус каждый раз непосредственно перед выполнением Javascript document.getElementById("text1").focus();.

public void javaFocus(final boolean shouldForceOpenKeyboard) {
    Thread t = new Thread("Java focusser thread") {
        public void run() {
            wv.requestFocus(View.FOCUS_DOWN);
            wv.loadUrl("javascript:focusser();");
            if(shouldForceOpenKeyboard) {
                InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                mgr.showSoftInput(wv, InputMethodManager.SHOW_IMPLICIT);
            }
        }
    };

    // Run on the View Thread.
    _current.runOnUiThread(t);
}

Кроме того, чтобы убедиться, что эта проблема не была исправлена ​​из-за фокуса, вызванного с помощью touch и т.д., я использую фоновый поток для запуска javaFocus() через 5 секунд отображаемого WebView. Модифицированный onCreate() приведен ниже.

..... More onCreate code before....
// Enable Alert calls  
wv.setWebChromeClient(new CustomWebChromeClient());

// For JS->Java calls
wv.addJavascriptInterface(this, "javautil");

setContentView(wv);

new Thread("After sometime Focus") {
    public void run() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        javaFocus(true);
    }
}.start();
.... onCreate() ends after this.... 

Ответы

Ответ 1

Возможно, веб-просмотр не имеет фокуса приложения. Попробуйте выполнить;

wv.requestFocus(View.FOCUS_DOWN);