[android] एंड्रॉइड सॉफ्ट कीबोर्ड को बंद / छुपाएं



Answers

इस पागलपन को स्पष्ट करने में मदद के लिए, मैं सॉफ्ट एंड्रॉइड के Google के निचले हास्यास्पद उपचार के लिए सभी एंड्रॉइड उपयोगकर्ताओं की तरफ से माफ़ी मांगना शुरू करना चाहता हूं। एक ही सरल सवाल के लिए, प्रत्येक अलग-अलग उत्तर हैं, क्योंकि अलग-अलग कारण यह है कि एंड्रॉइड में कई अन्य लोगों की तरह यह एपीआई बेहद डिज़ाइन किया गया है। मैं इसे बताने के लिए कोई विनम्र तरीका नहीं सोच सकता।

मैं कीबोर्ड को छिपाना चाहता हूं। मैं एंड्रॉइड को निम्नलिखित कथन के साथ प्रदान करने की उम्मीद करता हूं: Keyboard.hide() । समाप्त। आपका बहुत बहुत धन्यवाद। लेकिन एंड्रॉइड में एक समस्या है। कीबोर्ड को छुपाने के लिए आपको InputMethodManager का उपयोग करना होगा। ठीक है, ठीक है, यह कीबोर्ड के लिए एंड्रॉइड एपीआई है। परंतु! आईएमएम तक पहुंच प्राप्त करने के लिए आपको एक Context होना आवश्यक है। अब हमें एक समस्या है। मैं कुंजीपटल को एक स्थैतिक या उपयोगिता वर्ग से छिपाना चाहता हूं जिसका कोई उपयोग या किसी Context लिए आवश्यकता नहीं है। या एफएआर खराब है, आईएमएम की आवश्यकता है कि आप निर्दिष्ट करें (या इससे भी बदतर, क्या Window ) आप कुंजीपटल से छिपाना चाहते हैं।

यह कुंजीपटल को इतना चुनौतीपूर्ण छुपाता है। प्रिय Google: जब मैं एक केक के लिए नुस्खा देख रहा हूं, वहां पृथ्वी पर कोई पकाने की विधि नहीं है जो मुझे नुस्खा प्रदान करने से इनकार कर देगी जब तक कि मैं पहली बार डब्ल्यूएचओ का जवाब नहीं दूंगा और जहां इसे खाया जाएगा !!

यह दुखद कहानी बदसूरत सच्चाई के साथ समाप्त होती है: एंड्रॉइड कीबोर्ड को छिपाने के लिए, आपको पहचान के 2 रूप प्रदान करने होंगे: एक Context और या तो एक View या Window

मैंने एक स्थिर उपयोगिता विधि बनाई है जो बहुत ही कठिन काम कर सकती है, बशर्ते आप इसे किसी 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 टोकन लाने के लिए लक्षित Activity getCurrentFocus है।

लेकिन मान लीजिए कि आप DialogFragment में होस्ट किए गए DialogFragment से कीबोर्ड को छिपाना चाहते हैं? आप इसके लिए उपरोक्त विधि का उपयोग नहीं कर सकते हैं:

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 के बारे में

इसके बारे में जागरूक होने के लिए विवाद का एक और बिंदु है। डिफ़ॉल्ट रूप से, एंड्रॉइड स्वचालित रूप से प्रारंभिक फोकस को पहले EditText या आपकी Activity में फोकस करने योग्य नियंत्रण में असाइन करेगा। यह स्वाभाविक रूप से निम्नानुसार है कि इनपुट मोड (आमतौर पर सॉफ्ट कीबोर्ड) स्वयं को दिखाकर फोकस ईवेंट का जवाब देगा। AndroidManifest.xml में windowSoftInputMode विशेषता, जब राज्य पर सेट किया जाता है stateAlwaysHidden , कीबोर्ड को स्वचालित रूप से असाइन किए गए प्रारंभिक फ़ोकस को अनदेखा करने के लिए निर्देश देता है।

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

लगभग अविश्वसनीय रूप से, ऐसा लगता है कि जब आप नियंत्रण को स्पर्श करते हैं तो कीबोर्ड को खोलने से रोकने के लिए कुछ भी नहीं होता है (जब तक focusable="false" और / या focusableInTouchMode="false" नियंत्रण में असाइन नहीं किया जाता है)। जाहिर है, windowSoftInputMode सेटिंग केवल स्वचालित फ़ोकस ईवेंट पर लागू होती है, न कि स्पर्श ईवेंट से ट्रिगर की गई घटनाओं पर ध्यान केंद्रित करने के लिए।

इसलिए, stateAlwaysHidden से stateAlwaysHidden है वास्तव में बहुत खराब नामित है। इसे शायद इसके बजाय ignoreInitialFocus कहा जाना चाहिए।

उम्मीद है की यह मदद करेगा।

अद्यतन: खिड़की टोकन पाने के अधिक तरीके

यदि कोई केंद्रित दृश्य नहीं है (उदाहरण के लिए यदि आप अभी टुकड़े बदल गए हैं तो हो सकता है), ऐसे अन्य विचार भी हैं जो उपयोगी विंडो टोकन की आपूर्ति करेंगे।

ये उपरोक्त कोड के विकल्प हैं 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();

Question

मेरे पास मेरे लेआउट में एक EditText और एक Button है।

संपादन क्षेत्र में लिखने और Button पर क्लिक करने के बाद, मैं वर्चुअल कीबोर्ड को छिपाना चाहता हूं। मुझे लगता है कि यह कोड का एक साधारण टुकड़ा है, लेकिन मुझे इसका उदाहरण कहां मिल सकता है?




वैकल्पिक रूप से इसके आसपास के समाधान के लिए , यदि आप कुंजीपटल खोलने के लिए इस्तेमाल किए गए (एडिटटेक्स्ट) फ़ील्ड के संदर्भ में कहीं से भी सॉफ्ट कीबोर्ड बंद करना चाहते थे, लेकिन फ़ील्ड केंद्रित होने पर अभी भी ऐसा करना चाहता था, तो आप इसका उपयोग कर सकते थे यह (एक गतिविधि से):

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



If you want to close the soft keyboard during a unit or functional test, you can do so by clicking the "back button" from your test:

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

I put "back button" in quotes, since the above doesn't trigger the onBackPressed() for the Activity in question. It just closes the keyboard.

Make sure to pause for a little while before moving on, since it takes a little while to close the back button, so subsequent clicks to Views, etc., won't be registered until after a short pause (1 second is long enough ime).




Simple and Easy to use method, just call hideKeyboardFrom(YourActivity.this); to hide keyboard

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



कीबोर्ड को छुपाने के लिए मुझे एक और समाधान मिला:

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

यहां HIDE_IMPLICIT_ONLY की स्थिति में showFlag और 0 की स्थिति पर hiddenFlag । यह नरम कीबोर्ड को मजबूती से बंद कर देगा।




Just use this optimized code in your activity:

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



Thanks to this SO answer , I derived the following which, in my case, works nicely when scrolling through the the fragments of a 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);
    }
}



सौरभ पारीक का अब तक का सबसे अच्छा जवाब है।

हालांकि, सही झंडे का भी उपयोग कर सकते हैं।

/* 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 ... */
}



कृपया नीचे दिए गए कोड को कोड पर आज़माएं ()

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




मैं एक हेक्स नंबर इनपुट करने के लिए एक कस्टम कीबोर्ड का उपयोग कर रहा हूं, इसलिए मेरे पास आईएमएम कीबोर्ड नहीं दिख सकता है ...

V3.2.4_r1 setSoftInputShownOnFocus(boolean show) को मौसम को नियंत्रित करने के लिए जोड़ा गया था या जब टेक्स्टव्यू फोकस हो जाता है तो कुंजीपटल प्रदर्शित नहीं किया जाता था, लेकिन यह अभी भी छुपा हुआ है इसलिए प्रतिबिंब का उपयोग किया जाना चाहिए:

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 साथ बहुत अच्छे नतीजे मिले हैं (लेकिन बहुत दूर से), मेरे रूट व्यू से ViewTreeObserver की सहायता से जोड़ा गया है और फिर जांच कर रहा है कि कीबोर्ड इस तरह दिखाया गया है या नहीं:

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

यह अंतिम समाधान कुंजीपटल दूसरे के लिए कुंजीपटल दिखा सकता है और चयन हैंडल के साथ गड़बड़ कर सकता है।

कीबोर्ड में पूर्ण स्क्रीन में प्रवेश करते समय, ग्लोबललायआउट को कॉल नहीं किया जाता है। इससे बचने के लिए, TextView#setImeOptions(int) या TextView#setImeOptions(int) एक्सएमएल घोषणा में उपयोग करें:

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

अपडेट करें: बस यह पता चला कि कीबोर्ड को कभी भी दिखाने के लिए कौन से संवाद उपयोग नहीं करते हैं और सभी संस्करणों में काम करता है:

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



For my case, I was using the a SearchView in the actionbar. After a user performs a search, the keyboard would pop open again.

Using the InputMethodManager did not close the keyboard. I had to clearFocus and set the focusable of the search view to false:

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



I have the case, where my EditText can be located also in an AlertDialog , so the keyboard should be closed on dismiss. The following code seems to be working anywhere:

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



संक्षिप्त जवाब

अपने onEditorAction श्रोता में onEditorAction के साथ EditText के IME_ACTION_DONE onEditorAction पर कॉल करें

button.setOnClickListener(new OnClickListener() {

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

ड्रिल-डाउन

मुझे लगता है कि एंड्रॉइड के डिजाइन पैटर्न के साथ यह विधि बेहतर, सरल और अधिक गठबंधन है। उपरोक्त सरल उदाहरण (और आमतौर पर अधिकांश सामान्य मामलों में) में आपके पास एक EditText जिसमें फोकस होता है और यह आमतौर पर कुंजीपटल को पहली बार आमंत्रित करने वाला होता है (यह निश्चित रूप से इसे आमंत्रित करने में सक्षम है कई आम परिदृश्य)। इसी तरह, यह कीबोर्ड को रिलीज़ करने वाला एक होना चाहिए, आमतौर पर एक ImeAction द्वारा किया जा सकता है। बस देखें कि android:imeOptions="actionDone" साथ android:imeOptions="actionDone" व्यवहार करता है, आप उसी व्यवहार से वही व्यवहार प्राप्त करना चाहते हैं।

इस संबंधित उत्तर की जांच करें




protected void hideSoftKeyboard(EditText input) {
    input.setInputType(0);
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(input.getWindowToken(), 0);    
}



This worked for me for all the bizarre keyboard behavior

private boolean isKeyboardVisible() {
    Rect r = new Rect();
    //r will be populated with the coordinates of your view that area still visible.
    mRootView.getWindowVisibleDisplayFrame(r);

    int heightDiff = mRootView.getRootView().getHeight() - (r.bottom - r.top);
    return heightDiff > 100; // if more than 100 pixels, its probably a keyboard...
}

protected void showKeyboard() {
    if (isKeyboardVisible())
        return;
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if (getCurrentFocus() == null) {
        inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    } else {
        View view = getCurrentFocus();
        inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_FORCED);
    }
}

protected void hideKeyboard() {
    if (!isKeyboardVisible())
        return;
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    View view = getCurrentFocus();
    if (view == null) {
        if (inputMethodManager.isAcceptingText())
            inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS, 0);
    } else {
        if (view instanceof EditText)
            ((EditText) view).setText(((EditText) view).getText().toString()); // reset edit text bug on some keyboards bug
        inputMethodManager.hideSoftInputFromInputMethod(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}



Related