Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How disable softkeyboard in WebView

I need disable open softkeyboard in my WebView and in all edittexts in WebView (I do not access to thay because its is in WebView).

I try use 'android:windowSoftInputMode="stateAlwaysHidden"' in my Manifest file, but keyboard popup on when I click in editable field.

What is right solution for disable softkeyboard in WebView?

EDIT:

I find solution (thanks @g00dy in this post and @Kachi in post https://stackoverflow.com/a/9108219/1665964) for close keyboard after it open:

public class ActivityBrowser extends Activity 
 {
   private static WebView        webviewHTML;
   private static View           viewRootHTML;
   private static int            iViewRootHTMLHeightDifferent; 
   public  static Context        contextBrowser;

    {
      contextBrowser = this;
    }


   public class webViewClient extends WebViewClient
    {
      @Override
      public void onPageStarted( WebView view, String url, Bitmap favicon)
       {
         if( view == webviewHTML)  super.onPageStarted( view, url, favicon);
       }

      @Override
      public void onPageFinished( WebView view, String url)
       {
         if( view == webviewHTML)  super.onPageFinished( view, url);
       }

      @Override
      public boolean shouldOverrideUrlLoading( WebView view, String url)
       {
         if( view == webviewHTML)  view.loadUrl( url);
         return false;
         // return super.shouldOverrideUrlLoading( view, url);
       }

      @Override
      public void onReceivedError( WebView view, int errorCode, String description, String failingUrl)
       {
         if( view == webviewHTML)  ApplicationLeta.fPopup( getString( R.string.sPopupErrorSiteOpen) + " : " + description);
         // ActivityBrowser.this.finish();
       }

      public void onReceivedSslError( WebView view, SslErrorHandler handler, SslError error)
       {
         if( view == webviewHTML)  handler.proceed();
       }
    }


   @Override
   public boolean dispatchTouchEvent( MotionEvent motionEvent)
    {
      super.dispatchTouchEvent( motionEvent);

      if( motionEvent.getAction() == MotionEvent.ACTION_MOVE)  return true;

      if( motionEvent.getAction() == MotionEvent.ACTION_UP)
        {
          // do something
        }

      if( motionEvent.getAction() == MotionEvent.ACTION_UP)
        {
          // do something
        }
      return false;
    }


   @Override
   public void onBackPressed()
    {
    }


   @Override
   public void onWindowFocusChanged( boolean eFocus)
    {
      super.onWindowFocusChanged( eFocus);
      if( eFocus == false)
        {
          fKeyboardClose();

          new Thread( new Runnable()
           {
             @Override
             public void run()
              {
                try
                  {
                    Instrumentation inst = new Instrumentation();
                    inst.sendKeyDownUpSync( KeyEvent.KEYCODE_BACK);
                  }
                 catch( Exception e) {}
              }
           } ).start();
        }
    }


   private void fKeyboardClose()
    {
      InputMethodManager inputMethodManager = (InputMethodManager)getSystemService( Activity.INPUT_METHOD_SERVICE);
      inputMethodManager.hideSoftInputFromWindow( getCurrentFocus().getWindowToken(), 0);
    }


   public OnGlobalLayoutListener onGlobalLayoutListener = new OnGlobalLayoutListener()
    {
      @Override
      public void onGlobalLayout()
       {
         Rect rect = new Rect();
         viewRootHTML.getWindowVisibleDisplayFrame( rect);
         iViewRootHTMLHeightDifferent = viewRootHTML.getRootView().getHeight() - (rect.bottom - rect.top);
         if( iViewRootHTMLHeightDifferent > 50)  fKeyboardClose();
       }
    };

   @SuppressWarnings( "deprecation")
   @SuppressLint( "SetJavaScriptEnabled")
   public void onCreate( Bundle savedInstanceState)
    {
      super.onCreate( savedInstanceState);
      setContentView( R.layout.browser);

      if( savedInstanceState == null)
        {
          viewRootHTML = findViewById( R.id.linearLayoutHTML);
          viewRootHTML.getViewTreeObserver().addOnGlobalLayoutListener( onGlobalLayoutListener);

          webviewHTML = (WebView) findViewById( R.id.webviewHTML);
          WebSettings webSettings = webviewHTML.getSettings();
          webSettings.setJavaScriptEnabled( true);
          webSettings.setJavaScriptCanOpenWindowsAutomatically( true);
          webviewHTML.setWebViewClient( new wiewClient());
          webviewHTML.loadUrl( ApplicationLeta.sAppInterviewURL);
        }
    }
 }

This code also close system message "Edit text / Input method" when user longpress on input field.

But! This code close keyboard only after it open. Keyboard stay visible a few miliseconds and user (fast user) can press any key on keyboard. This is not best situation.

Maybe exist best way to 100% disable keyboard without open it?

like image 986
Tapa Save Avatar asked Jul 16 '13 08:07

Tapa Save


3 Answers

This answer is for those who do not want the keyboard to pop up, but still want to let the user interact with the input box. Either by hardware keyboards or touch cursor

You could take into consideration of an approach from both Javascript and Android combined.

Case - we have a WebView (In MainActivity) that has input boxes and we don't want Android to pop the soft keyboard after the user click the textbox

Below is how to achieve hiding: We need to use both Javascript and Java to achieve this on Android:


First on Javascript side

We can create a JS file to handle the webpage displayed in the WebView, and apply it to the webview by calling this in the onCreate of the MainActivity i.e:

ExtendedWebView webView = findViewById(R.id.webview_id);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
webView.addJavascriptInterface(new MyJavascript(), "_my_javascript");

We can then have the JS checking each of the input boxes on the webpage displayed. And if the input box is the type we are interested in we can then apply this function to the input_box we are interested in:

function hide_soft_keyboard(input_box) {
      input_box.addEventListener("click", function() {
              input_box.blur(); // very important call
              input_box.focus();// very important call x2
      });
}

The above code, force OnClick event of the input box to be out of focus first and then focus. And this is the key to hide the keyboard.

Second on Java side

Now that we have the JS part taken care of, we need to extend the WebView we are using to override a specific method provided by the WebView class from the framework:

@Override 
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        hideKeyboard();
        return super.onCreateInputConnection(outAttrs);
}

What this method does is to create an input connected to the input_box in the HTML webpage displayed in webview, and this method is called the first time you click an input box on the webview. However, this method will only be called once before the input connection is established, which means if you call hideKeyboard() in this method, it will only work the first time user clicks it, but not the second time.

BUT, together with the JS change we have earlier, hideKeyboard() will work... How?

Since in the JS file we created earlier we forced the onClick of the input box to trigger a blur() call, which closes the current input connection, and followed by a focus() call to let android focus on to the same input_box again, this will force the onCreateInputConnection() method to be called again, which triggers the hideKeyboard() method, allowing user to interact with the input box without the soft keyboard popping out, which successfully answered this question: Disable SoftKeyboard inside a WebView

private void hideKeyboard() {
        post(new Runnable() {
            @Override
            public void run() {
                InputMethodManager imm = (InputMethodManager) getContext()
                    .getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) imm.hideSoftInputFromWindow(getRootView().getWindowToken(), 0);
            }
        });
}

Source: I worked on a device with hardware num keys, but has no physical qwerty keyboard, and found out this solution when trying to disable soft keyboard popping out only when input box type is limited to numbers.

like image 56
Haomin Avatar answered Sep 20 '22 20:09

Haomin


This answer worked for me (provided by Android Weblineindia): https://stackoverflow.com/a/29409478/4813198

Add following code in main (parent) layout in your layout.xml:

>
>    android:descendantFocusability="blocksDescendants"
>

and set following properties in your webview:

>    android:focusable="false"
>    android:focusableInTouchMode="true"
like image 44
Sunil Avatar answered Sep 17 '22 20:09

Sunil


None of this seemed to work Sunil's answer didn't work when i put it in the layout. It led me to look at all the webview settings so i did this in the webview settings and it worked. No keyboard poping up.

webview = (WebView) findViewById(R.id.webview);
webview.setFocusableInTouchMode(false);
webview.setFocusable(false);
webview.loadUrl("file:///android_asset/index.html");
like image 36
Ashtar Avatar answered Sep 17 '22 20:09

Ashtar