android-layout show - 關閉/隱藏Android軟鍵盤




keyboard close (25)

感謝這個SO答案,我推導出以下內容,在我的情況下,滾動瀏覽ViewPager的片段時效果很好...

private void hideKeyboard() {   
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

private void showKeyboard() {   
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
    }
}

我的佈局中有一個EditText和一個Button

在編輯字段中寫入並單擊Button ,我想隱藏虛擬鍵盤。 我假設這是一段簡單的代碼,但我在哪裡可以找到它的一個例子?


請在onCreate()嘗試以下代碼

EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);

Meier的解決方案也適用於我。 在我的情況下,我的應用程序的頂級是tabHost,我想在切換標籤時隱藏關鍵字 - 我從tabHost視圖中獲取窗口標記。

tabHost.setOnTabChangedListener(new OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(tabHost.getApplicationWindowToken(), 0);
    }
}

只需在您的活動中使用此優化代碼:

if (this.getCurrentFocus() != null) {
    InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

以下是你在Mono for Android(AKA MonoDroid)中的表現

InputMethodManager imm = GetSystemService (Context.InputMethodService) as InputMethodManager;
if (imm != null)
    imm.HideSoftInputFromWindow (searchbox.WindowToken , 0);

在某些情況下,除其他所有方法外,此方法都可以使用 這節省了我的一天:)

public static void hideSoftKeyboard(Activity activity) {
    if (activity != null) {
        InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (activity.getCurrentFocus() != null && inputManager != null) {
            inputManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
            inputManager.hideSoftInputFromInputMethod(activity.getCurrentFocus().getWindowToken(), 0);
        }
    }
}

public static void hideSoftKeyboard(View view) {
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputManager != null) {
            inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }
}

到目前為止, Saurabh Pareek有最好的答案。

不過,不妨使用正確的旗幟。

/* hide keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
    .toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

/* show keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
    .toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);

實際使用的例子

/* click button */
public void onClick(View view) {      
  /* hide keyboard */
  ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
      .toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

  /* start loader to check parameters ... */
}

/* loader finished */
public void onLoadFinished(Loader<Object> loader, Object data) {
    /* parameters not valid ... */

    /* show keyboard */
    ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
        .toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);

    /* parameters valid ... */
}

簡短的回答

OnClick偵聽onEditorAction中,使用IME_ACTION_DONE調用EditTextIME_ACTION_DONE

button.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        someEditText.onEditorAction(EditorInfo.IME_ACTION_DONE)
    }
});

深入研究

我覺得這種方法更好,更簡單,更符合Android的設計模式。 在上面的簡單示例中(通常在大多數常見情況下),您將擁有一個具有焦點的EditText ,它通常也是首先調用鍵盤的鍵盤(它肯定能夠調用它)許多常見情況)。 以同樣的方式, 應該是釋放鍵盤的那個,通常可以通過ImeAction來完成。 只要看看帶有android:imeOptions="actionDone"EditText如何表現,你想用同樣的方法實現相同的行為。

檢查這個相關的答案


簡單易用的方法,只需調用hideKeyboardFrom(YourActivity.this); 隱藏鍵盤

/**
 * This method is used to hide keyboard
 * @param activity
 */
public static void hideKeyboardFrom(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

對於我的情況,我在操作欄中使用了SearchView。用戶執行搜索後,鍵盤將再次彈出。

使用InputMethodManager沒有關閉鍵盤。我不得不clearFocus並將搜索視圖的焦點設置為false:

mSearchView.clearFocus();
mSearchView.setFocusable(false);

我正在使用自定義鍵盤輸入​​十六進制數字,因此我無法顯示IMM鍵盤...

在v3.2.4_r1中添加了setSoftInputShownOnFocus(boolean show)以控制天氣或不顯示TextView獲得焦點時的鍵盤,但它仍然隱藏,因此必須使用反射:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    try {
        Method method = TextView.class.getMethod("setSoftInputShownOnFocus", boolean.class);
        method.invoke(mEditText, false);
    } catch (Exception e) {
        // Fallback to the second method
    }
}

對於舊版本,我使用OnGlobalLayoutListener獲得了非常好的結果(但遠非完美),在我的根視圖中藉助OnGlobalLayoutListener添加,然後檢查鍵盤是否顯示如下:

@Override
public void onGlobalLayout() {
    Configuration config = getResources().getConfiguration();

    // Dont allow the default keyboard to show up
    if (config.keyboardHidden != Configuration.KEYBOARDHIDDEN_YES) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(mRootView.getWindowToken(), 0);
    }
}

最後一個解決方案可以顯示鍵盤一瞬間,並與選擇手柄混淆。

當鍵盤進入全屏時,不會調用onGlobalLayout。 為避免這種情況,請使用TextView#setImeOptions(int)或TextView XML聲明:

android:imeOptions="actionNone|actionUnspecified|flagNoFullscreen|flagNoExtractUi"

更新:剛剛找到哪些對話框用於永不顯示鍵盤並適用於所有版本:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

我還有一個隱藏鍵盤的解決方案:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);

這裡在HIDE_IMPLICIT_ONLY的位置傳遞HIDE_IMPLICIT_ONLY ,在HIDE_IMPLICIT_ONLY的位置showFlag 0 。 它會強行關閉軟鍵盤。


或者到這一切它的解決方案,如果你想關閉軟鍵盤從任何地方,而不必是用於打開鍵盤(EditText上)字段的引用,但仍然希望這樣做,如果該領域的重點,你可以使用這(來自一項活動):

if (getCurrentFocus() != null) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

上面的答案適用於不同的場景但是如果你想在視圖中隱藏鍵盤並努力獲得正確的上下文,請嘗試以下方法:

setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        hideSoftKeyBoardOnTabClicked(v);
    }
}

private void hideSoftKeyBoardOnTabClicked(View v) {
    if (v != null && context != null) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

並從構造函數獲取上下文:)

public View/RelativeLayout/so and so (Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.context = context;
    init();
}

為了幫助澄清這種瘋狂,我想首先代表所有Android用戶道歉,谷歌對軟鍵盤的徹頭徹尾的荒謬處理。 對於同樣簡單的問題,有很多答案,每個不同的原因是因為這個API與Android中的許多其他答案一樣,設計非常糟糕。 我可以想到沒有禮貌的方式陳述它。

我想隱藏鍵盤。 我期望為Android提供以下聲明: Keyboard.hide() 。 結束。 非常感謝你。 但Android存在問題。 您必須使用InputMethodManager來隱藏鍵盤。 好的,很好,這是Android的鍵盤API。 但! 您需要具有Context才能訪問IMM。 現在我們遇到了問題。 我可能想要從沒有任何使用或不需要任何Context的靜態或實用程序類中隱藏鍵盤。 或者更糟糕的是,IMM要求您指定要隱藏鍵盤FROM的View (甚至更糟糕的是什麼Window )。

這使得隱藏鍵盤變得如此具有挑戰性。 親愛的谷歌:當我查找蛋糕的配方時,地球上沒有RecipeProvider拒絕向我提供配方,除非我第一次回答世界衛生組織,蛋糕將被吃掉,哪裡會被吃掉!

這個悲傷的故事以醜陋的事實告終:要隱藏Android鍵盤,您需要提供兩種形式的識別: Context以及ViewWindow

我已經創建了一個靜態實用程序方法,只要你從一個Activity調用它就可以非常穩定地完成工作。

public static void hideKeyboard(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    //Find the currently focused view, so we can grab the correct window token from it.
    View view = activity.getCurrentFocus();
    //If no view currently has focus, create a new one, just so we can grab a window token from it
    if (view == null) {
        view = new View(activity);
    }
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

請注意,此實用程序方法僅在從Activity調用時才有效! 上面的方法調用目標Activity getCurrentFocus來獲取正確的窗口標記。

但是假設您想要從DialogFragment託管的EditText隱藏鍵盤? 你不能使用上面的方法:

hideKeyboard(getActivity()); //won't work

這將無效,因為您將傳遞對Fragment的主機Activity的引用,當Fragment ,它將沒有集中控制! 哇! 因此,為了隱藏鍵盤中的碎片,我採用較低級別,更常見,更醜陋:

public static void hideKeyboardFrom(Context context, View view) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

以下是從更多時間浪費在追逐此解決方案中收集到的一些其他信息:

關於windowSoftInputMode

還有另一個爭論點需要注意。 默認情況下,Android會自動將初始焦點分配給Activity的第一個EditText或focusable控件。 由此可見,InputMethod(通常是軟鍵盤)將通過顯示自身來響應焦點事件。 AndroidManifest.xmlwindowSoftInputMode屬性設置為stateAlwaysHidden ,指示鍵盤忽略此自動分配的初始焦點。

<activity
    android:name=".MyActivity"
    android:windowSoftInputMode="stateAlwaysHidden"/>

幾乎令人難以置信的是,當您觸摸控件時,似乎無法阻止鍵盤打開(除非將focusable="false"和/或focusableInTouchMode="false"分配給控件)。 顯然,windowSoftInputMode設置僅適用於自動焦點事件,而不適用於觸發觸摸事件觸發的事件。

因此, stateAlwaysHidden名字確實非常糟糕。 它也許應該被稱為ignoreInitialFocus

希望這可以幫助。

更新:獲取窗口令牌的更多方法

如果沒有焦點視圖(例如,如果你剛剛更改了片段就會發生),還有其他視圖將提供有用的窗口令牌。

if (view == null) view = new View(activity);這些是上述代碼的替代品if (view == null) view = new View(activity); 這些並未明確提及您的活動。

在片段類中:

view = getView().getRootView().getWindowToken();

給定片段fragment作為參數:

view = fragment.getView().getRootView().getWindowToken();

從您的內容正文開始:

view = findViewById(android.R.id.content).getRootView().getWindowToken();

更新2:清除焦點以避免在從後台打開應用程序時再次顯示鍵盤

將此行添加到方法的末尾:

view.clearFocus();


從搜索到這裡,我找到了一個適合我的答案

// Show soft-keyboard:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

// Hide soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

更新:我不知道為什麼這個解決方案不再起作用(我剛剛在Android 23上測試過)。 請使用Saurabh Pareek的解決方案。 這裡是:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
//Hide:
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
//Show
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

老答案:

//Show soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

您可以使用InputMethodManager強制Android隱藏虛擬鍵盤,調用hideSoftInputFromWindow ,傳入包含焦點視圖的窗口的標記。

// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {  
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

這將強制鍵盤在所有情況下都被隱藏。 在某些情況下,您需要傳入InputMethodManager.HIDE_IMPLICIT_ONLY作為第二個參數,以確保在用戶未明確強制顯示鍵盤時(僅通過按住菜單)隱藏鍵盤。

注意:如果要在Kotlin中執行此操作,請使用: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager


我花了兩天多的時間來處理帖子中發布的所有解決方案,並發現它們缺乏這種或那種方式。 我的確切要求是有一個100%可靠性的按鈕顯示或隱藏屏幕鍵盤。 當鍵盤處於隱藏狀態時,無論用戶點擊什麼輸入字段,都不應重新出現。 當它處於可見狀態時,無論用戶點擊什麼按鈕,鍵盤都不會消失。 這需要在Android 2.2+上運行,直到最新的設備。

你可以在我的app clean RPN中看到這個的有效實現。

在許多不同的手機(包括froyo和薑餅設備)上測試了許多建議的答案後,很明顯Android應用程序可以可靠地:

  1. 暫時隱藏鍵盤。 當用戶聚焦新文本字段時,它將再次重新出現。
  2. 在活動開始時顯示鍵盤,並在活動上設置一個標誌,指示鍵盤應始終可見。 只有在活動初始化時才能設置此標誌。
  3. 將活動標記為從不顯示或允許使用鍵盤。 只有在活動初始化時才能設置此標誌。

對我來說,暫時隱藏鍵盤是不夠的。 在某些設備上,只要新的文本字段被聚焦,它就會重新出現。 由於我的應用程序在一個頁面上使用多個文本字段,因此聚焦新文本字段將導致隱藏鍵盤再次彈回。

不幸的是,列表中的第2項和第3項僅在啟動活動時才具有可靠性。活動變得可見後,您無法永久隱藏或顯示鍵盤。訣竅是當用戶按下鍵盤切換按鈕時實際重啟您的活動。在我的應用程序中,當用戶按下切換鍵盤按鈕時,運行以下代碼:

private void toggleKeyboard(){

    if(keypadPager.getVisibility() == View.VISIBLE){
        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        Bundle state = new Bundle();
        onSaveInstanceState(state);
        state.putBoolean(SHOW_KEYBOARD, true);
        i.putExtras(state);

        startActivity(i);
    }
    else{
        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        Bundle state = new Bundle();
        onSaveInstanceState(state);
        state.putBoolean(SHOW_KEYBOARD, false);
        i.putExtras(state);

        startActivity(i);
    }
}

這會導致當前活動將其狀態保存到Bundle中,然後啟動活動,通過布爾值來指示是否應顯示或隱藏鍵盤。

在onCreate方法中,運行以下代碼:

if(bundle.getBoolean(SHOW_KEYBOARD)){
    ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(newEquationText,0);
    getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
else{
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
            WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}

如果應該顯示軟鍵盤,則告訴InputMethodManager顯示鍵盤,並指示窗口使軟輸入始終可見。如果應隱藏軟鍵盤,則設置WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM。

這種方法可以在我測試過的所有設備上可靠運行 - 從運行Android 2.2的4歲HTC手機到運行4.2.2的nexus 7。這種方法的唯一缺點是你需要小心處理後退按鈕。由於我的應用程序基本上只有一個屏幕(它是一個計算器),我可以覆蓋onBackPressed()並返回到設備主屏幕。


我有這種情況,我的EditText位置也可以在一個AlertDialog,所以鍵盤應該關閉解僱。以下代碼似乎在任何地方都可以使用:

public static void hideKeyboard( Activity activity ) {
    InputMethodManager imm = (InputMethodManager)activity.getSystemService( Context.INPUT_METHOD_SERVICE );
    View f = activity.getCurrentFocus();
    if( null != f && null != f.getWindowToken() && EditText.class.isAssignableFrom( f.getClass() ) )
        imm.hideSoftInputFromWindow( f.getWindowToken(), 0 );
    else 
        activity.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN );
}

這應該工作:

public class KeyBoard {

    public static void show(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY); // show
    }

    public static void hide(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); // hide
    }

    public static void toggle(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        if (imm.isActive()){
            hide(activity); 
        } else {
            show(activity); 
        }
    }
}

KeyBoard.toggle(activity);

用這個

this.getWindow().setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

如果要在單元或功能測試期間關閉軟鍵盤,可以通過單擊測試中的“後退按鈕”來執行此操作:

// Close the soft keyboard from a Test
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);

我把“後退按鈕”放在引號中,因為上面沒有觸發有onBackPressed()問題的Activity。它只是關閉鍵盤。

確保在繼續之前暫停一段時間,因為關閉後退按鈕需要一點時間,因此後續點擊視圖等將在短暫停頓後暫停(1秒足夠長時間) )。


我幾乎已經嘗試了所有這些答案,我有一些隨機問題,尤其是三星Galaxy s5。

我最終得到的是強制展示和隱藏,它完美地運作:

/**
 * Force show softKeyboard.
 */
public static void forceShow(@NonNull Context context) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}

/**
 * Force hide softKeyboard.
 */
public static void forceHide(@NonNull Activity activity, @NonNull EditText editText) {
    if (activity.getCurrentFocus() == null || !(activity.getCurrentFocus() instanceof EditText)) {
        editText.requestFocus();
    }
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
    activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}

更新2

@Override
    protected void onResume() {
        super.onResume();
        mUserNameEdit.requestFocus();

        mUserNameEdit.postDelayed(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                InputMethodManager keyboard = (InputMethodManager)
                getSystemService(Context.INPUT_METHOD_SERVICE);
                keyboard.showSoftInput(mUserNameEdit, 0);
            }
        },200); //use 300 to make it run when coming back from lock screen
    }

我非常努力地嘗試並找到了一個解決方案...每當一個新的活動開始,然後鍵槃無法打開,但我們可以在onResume中使用Runnable ,並且它工作正常,所以請嘗試此代碼並檢查...

更新1

在你的AppLogin.java添加這一行

mUserNameEdit.requestFocus();

和你的AppList.java這一行

listview.requestFocus()'

之後檢查你的應用程序是否工作不正常,然後在你的AndroidManifest.xml文件中添加這行

<activity android:name=".AppLogin" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name=".AppList" android:configChanges="keyboard|orientation"></activity>

原始答案

 InputMethodManager imm = (InputMethodManager)this.getSystemService(Service.INPUT_METHOD_SERVICE);

為隱藏鍵盤

 imm.hideSoftInputFromWindow(ed.getWindowToken(), 0); 

為顯示鍵盤

 imm.showSoftInput(ed, 0);

專注於EditText

 ed.requestFocus();

ed是EditText





android android-layout android-softkeyboard android-input-method soft-keyboard