10

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?

Community
  • 1
  • 1
Tapa Save
  • 4,276
  • 4
  • 30
  • 52

6 Answers6

8

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"
Community
  • 1
  • 1
Sunil
  • 81
  • 2
  • 8
1

For the keyboard hidden state:

public void hideSoftKeyboard(View v) {
            Activity activity = (Activity) v.getContext();
            InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
        }

To disable the EditTexts:

Set android:editable="false" in the layout of them EditText.setFocusable(false) in the activity.

EDIT:

To detect the click event in the WebView use this:

 mWebView.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            // The code of the hiding goest here, just call hideSoftKeyboard(View v);
            return false;  
            }     
        }); 
g00dy
  • 6,652
  • 2
  • 28
  • 42
  • 1
    I do not have access to change attributes of the EditText because I have only my WebView. – Tapa Save Jul 16 '13 at 09:00
  • So you don't have rights to change the attributes of the `EditText`, which is inside of a `WebView`, which you have access to - how come? What is the content of the `WebView`? Are you visualizing a web page under your control or another random web page? – g00dy Jul 16 '13 at 09:03
  • You should instead try to detect the click, i'll edit my post. – g00dy Jul 16 '13 at 09:05
  • WebView have random content from internet. – Tapa Save Jul 16 '13 at 09:06
  • I already have onTouch code. I add your code for hide keyboard in onTouch (in case when event.getAction() == MotionEvent.ACTION_UP), but keyboard allways popup on :( – Tapa Save Jul 16 '13 at 09:13
  • Why not try the general `onTouch()`, without specifying the event. This will let you see if this even works on principal. Then if you like, you can try with filtering different events, but check this one for beginning. – g00dy Jul 16 '13 at 09:18
  • I try in general onTouch(), but no success. Any idea? – Tapa Save Jul 16 '13 at 10:13
  • You tried `hideSoftKeyboard();` and then `return false;` - right? – g00dy Jul 16 '13 at 10:28
  • Or you can slo try with `getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);`. – g00dy Jul 16 '13 at 10:29
  • I add code in my case in first post for close keyboard after it open. But I dont find solution for disabling keyboard without open it. Any idea? – Tapa Save Jul 17 '13 at 06:22
  • Well, I think that if you clear the focus on the `WebView`, this will prevent the keyboard from ever appearing on it, but this might interfere with the clicks on the `View`. This is as far as I can help, I don't have any idea how to stop the keyboard from ever appearing on principal. Another thing is to add `android:windowSoftInputMode="adjustPan"` to the `WebView` in order for it not to resize when the keyboard appears. – g00dy Jul 17 '13 at 06:45
1

A kind of hack solution which came to my mind but still does what is required - hides the keyboard so user will not see it:

public class WebViewEx extends WebView {

    private Handler mHandler;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        ensureKeyboard();
        return super.onTouchEvent(event);
    }

    private void ensureKeyboard() {
        if(mHandler == null){
            mHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    closeKeyboard();
                    sendEmptyMessageDelayed(0, 10);
                }
            };
        }
        mHandler.removeCallbacksAndMessages(null);
        mHandler.sendEmptyMessage(0);
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mHandler.removeCallbacksAndMessages(null);
            }
        }, 300);
    }

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

}

Feel free to play with the delays to minimize overhead because of rapid call of a function during the predefined period. I believe optimal values may vary depending on device.

vir us
  • 7,517
  • 3
  • 43
  • 55
1

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");
Ashtar
  • 11
  • 1
1

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.

Haomin
  • 479
  • 5
  • 9
-1

Try such a solution, it's pretty simple:

final WebView webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);  

final String js = "javascript: var allInputs = document.getElementsByTagName('input'); for (var i = 0, len = allInputs.length; i < len; ++i) { allInputs[i].readOnly = true;}";
webView.setWebViewClient(new WebViewClient(){
    @Override
    public void onPageFinished(WebView view, String url) {
        if (Build.VERSION.SDK_INT >= 19) {
            view.evaluateJavascript(js, new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String s) { }
        });
        } else {
            view.loadUrl(js);
        }
    }
});
webView.loadUrl("https://www.google.de/");
yital9
  • 6,038
  • 13
  • 37
  • 51