簡體   English   中英

如何在WebView中禁用軟鍵盤

[英]How disable softkeyboard in WebView

我需要在我的WebView和WebView的所有edittexts中禁用打開軟鍵盤(我不能訪問因為它在WebView中)。

我嘗試在我的清單文件中使用'android:windowSoftInputMode =“stateAlwaysHidden”',但是當我點擊可編輯字段時鍵盤彈出。

什么是在WebView中禁用軟鍵盤的正確解決方案?

編輯:

我發現解決方案(在這篇文章中感謝@ g00dy,在https://stackoverflow.com/a/9108219/1665964后感謝@Kachi)打開后關閉鍵盤:

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);
        }
    }
 }

當用戶在輸入字段上長按時,此代碼也會關閉系統消息“編輯文本/輸入法”。

但! 此代碼僅在打開后關閉鍵盤。 鍵盤保持可見幾毫秒,用戶(快速用戶)可以按鍵盤上的任意鍵。 這不是最好的情況。

也許存在最好的方法100%禁用鍵盤而不打開它?

這個答案對我有用(由Android Weblineindia提供): https ://stackoverflow.com/a/29409478/4813198

在layout.xml中的main(父)布局中添加以下代碼:

>
>    android:descendantFocusability="blocksDescendants"
>

並在webview中設置以下屬性:

>    android:focusable="false"
>    android:focusableInTouchMode="true"

對於鍵盤隱藏狀態:

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);
        }

要禁用EditTexts

在活動中的EditText.setFocusable(false)布局中設置android:editable="false"

編輯:

要在WebView檢測click事件,請使用以下命令:

 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;  
            }     
        }); 

我想到了一種黑客攻擊解決方案,但仍然可以執行所需操作 - 隱藏鍵盤以便用戶不會看到它:

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);
    }

}

由於在預定義時間段內快速調用功能,因此可以隨意使用延遲來最小化開銷。 我認為最佳值可能因設備而異。

當我把它放在布局中時,Sunil的答案不起作用。 它讓我看看所有的webview設置,所以我在webview設置中這樣做,並且它工作。 沒有鍵盤彈出。

webview = (WebView) findViewById(R.id.webview);
webview.setFocusableInTouchMode(false);
webview.setFocusable(false);
webview.loadUrl("file:///android_asset/index.html");

這個答案適用於那些不想彈出鍵盤,但仍想讓用戶與輸入框進行交互的人。 通過硬件鍵盤或觸摸光標

您可以考慮Javascript和Android結合使用的方法。

案例 - 我們有一個帶有輸入框的WebView(在MainActivity中),我們不希望Android在用戶點擊文本框后彈出軟鍵盤

下面是如何實現隱藏 :我們需要使用Javascript和Java在Android上實現這一點:


首先在Javascript方面

我們可以創建一個JS文件來處理WebView中顯示的網頁,並通過在MainActivity的onCreate中調用它來將其應用到webview,即:

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

然后我們可以讓JS檢查顯示的網頁上的每個輸入框。 如果輸入框是我們感興趣的類型,那么我們可以將此函數應用於我們感興趣的input_box:

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

上面的代碼,強制輸入框的OnClick事件先聚焦,然后聚焦。 這是隱藏鍵盤的關鍵。

其次是Java方面

現在我們已經處理了JS部分,我們需要擴展我們用來覆蓋框架中WebView類提供的特定方法的WebView:

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

此方法的作用是在webview中顯示的HTML網頁中創建連接到input_box的輸入,並且在第一次單擊webview上的輸入框時調用此方法。 但是,此方法僅在建立輸入連接之前調用一次,這意味着如果在此方法中調用hideKeyboard(),它將僅在用戶第一次單擊它時工作,而不是第二次。

但是,與我們之前的JS更改一起,hideKeyboard()將起作用......怎么樣?

因為在我們之前創建的JS文件中,我們強制輸入框的onClick觸發一個blur()調用,它關閉當前的輸入連接,然后調用focus()來讓android再次關注同一個input_box,這將強制再次調用onCreateInputConnection()方法,這會觸發hideKeyboard()方法,允許用戶在沒有軟鍵盤彈出的情況下與輸入框交互,這成功回答了這個問題: 在WebView中禁用SoftKeyboard

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);
            }
        });
}

來源:我在一台帶有硬件數字鍵的設備上工作,但沒有物理qwerty鍵盤,並且在嘗試禁用軟鍵盤彈出時,只有當輸入框類型僅限於數字時才能找到此解決方案。

嘗試這樣的解決方案,它非常簡單:

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/");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM