Android WebView - 使用Javascript设置HTML字段焦点

时间:2011-04-14 11:56:16

标签: javascript android javascript-events webview setfocus

我有一个只有一个可见的WebView组件的应用程序,它用于显示一些动态生成的HTML(也可以运行Javascript)。它已启用WebView

对于几页我尝试在页面加载完成后设置其中一个输入文本框的焦点 - 不通过 Body onLoad(),而是通过JS调用页面完成加载后,即在onPageFinished()中。大多数javascript执行正常

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

但是当我使用相同的调用来执行document.getElementById('text1').focus()时 - 光标会到达元素,但Soft Keyboard不会弹出。从页面上的按钮执行时,相同的javascript代码确实具有所需的效果。

我附上了 3个按钮

的源代码
  1. Focus Text1 - 将光标放在text1上并弹出软键盘。
  2. Java Focus Text1 - 调用Java来执行相同的JS。仅显示光标而不弹出键盘
  3. Java Focus Text1 And Keyboard Open - 从Java和Forces Keyboard调用JS打开。
  4. 我的理解是JS执行应该是相同的,无论是使用按钮/事件从浏览器执行还是通过WebView.loadURL()从Java发送。

    这是我的查询

    1. 使用Button#2时我遗失了什么?这就是我当前代码的方式,我只看到光标已设置但SoftKeyboard无法打开。
    2. 当我使用Button#3中写的逻辑时,我有时看不到光标在场上但是给了我想要的效果,当我在弹出的键盘中输入内容时光标变得可见。 / LI>
    3. 我在Button#2中看到的行为可能是Android JS执行中的错误吗?或者可能是WebView没有焦点,这就是为什么只显示光标?我也试过webview.requestFocus() - 我不能写requestFocusOnTouch(),因为它是我唯一拥有的视图,我希望它会自动聚焦。
    4. 演示行为的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 要使其工作,您需要在实际的JS焦点调用之前使用wv.requestFocus(View.FOCUS_DOWN)。我将上面的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);
      }
      

      另外为了确保由于通过触摸等触发焦点而没有修复此问题,我使用后台线程在WebView显示5秒后启动javaFocus()。修改后的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 个答案:

答案 0 :(得分:7)

可能是webview没有应用程序焦点。尝试执行;

wv.requestFocus(View.FOCUS_DOWN);