Soru Android Soft Klavye'yi kapatın / gizleyin


Benim bir EditText ve bir Button benim düzenimde.

Düzenleme alanında yazdıktan ve ButtonSanal klavyeyi gizlemek istiyorum. Bunun basit bir kod parçası olduğunu varsayalım, ama bunun bir örneğini nerede bulabilirim?


3093


Menşei


Onay kutuları ve radyolar gibi tek bir EditText ve birkaç düğmeniz varsa ne olur? Klavyeye ihtiyacınız olan tek yer, tek EditText'te. Klavyeyi gizlemek için başka bir şeyin seçildiğini / tıklandığını bilmek için nasıl kayıt oldunuz? - AlikElzin-kilaka
aptal hissediyorum. ICS'de klavyeyi gizleyemiyorum. Tüm yöntemleri burada denedim ve onların kombinasyonları. Asla. Bunu gösterme yöntemi işe yaramaz, ancak ne belirirse kazansın, saklanma işaretlerini, tezahürleri ya da mumları herhangi bir aziz için saklayamam. Klavye gösterisinde her zaman şunu görüyorum: I / LatinIME (396): InputType.TYPE_NULL belirtildi W / LatinIME (396): Beklenmeyen girdi sınıfı: inputType = 0x00000000 imeOptions = 0x00000000 - rupps
/ ** * Bu yöntem, yumuşak klavyeyi gizlemek için kullanılır. * @param etkinliği * / public void hideSoftKeyboard (Etkinlik etkinliği) {InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService (Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow (activity.getCurrentFocus (). getWindowToken (), 0); } - Harshal Benake
Bu kadar basit bir sorunun çok popüler olması çok üzücü. - lang2
Evet, doğru, Android gibi basit şeyler için bir ve iki katlı çözümler. - milosmns


Cevaplar:


Bu deliliğin açıklığa kavuşturulmasına yardımcı olmak için, Google'ın yazılım klavyesinin düpedüz gülünç tedavisi için tüm Android kullanıcıları adına özür dilemeye başlamak istiyorum. Aynı basit soru için bu kadar farklı cevapların her birinin nedeni, Android'deki diğer birçokları gibi bu API'nın korkunç bir şekilde tasarlanmış olmasıdır. Bunu belirtmek için kibar bir yol düşünemiyorum.

Klavyeyi gizlemek istiyorum. Android’e aşağıdaki ifadeyi sunmayı umuyorum: Keyboard.hide(). Son. Çok teşekkür ederim. Ancak Android'in bir sorunu var. Kullanmalısınız InputMethodManager klavyeyi gizlemek için Tamam, tamam, bu Android'in klavyeye ait API'sidir. FAKAT! Sahip olmak için Context IMM'ye erişmek için. Şimdi bir sorunumuz var. Klavyeyi, herhangi bir kullanımı olmayan veya herhangi bir gereksinimi olmayan bir statik veya yardımcı sınıftan gizlemek isteyebilirim. Context. Ya da FAR daha da kötüsü, IMM neyi belirtmeniz gerektiğini View (veya daha da kötüsü, ne Window) Klavyeyi gizlemek istediğinizde.

Klavyeyi saklamayı bu kadar zorlaştıran şey budur. Sevgili Google: Bir pasta tarifi ararken, hayır RecipeProvider Yeryüzünde bana bu tarifi vermeyi reddeden WHO'yu ilk cevaplamadığım sürece pasta YİYER tarafından yenilecek ve nerede yenecek?

Bu hüzünlü hikaye çirkin bir gerçekle sona eriyor: Android klavyesini gizlemek için, 2 kimlik formu sağlamanız gerekecektir: Context ve ya View ya da Window.

İşi sağlam bir şekilde yapabilmeniz için bir çok işe yarar bir statik yardımcı program yöntemi oluşturdum. 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);
}

SADECE bu çağrının bir Activity! Yukarıdaki yöntem çağrıları getCurrentFocus hedefin Activity uygun pencere belirteci almak için.

Ancak, klavyeyi bir EditText bir barındırılan DialogFragment? Bunun için yukarıdaki yöntemi kullanamazsınız:

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

Bu işe yaramaz çünkü Fragmentev sahibi Activityiken, odaklanmış kontrole sahip olmayacaktır. Fragment gösterilir! Vaov! Bu yüzden, klavyeyi parçalardan saklamak için, daha alt düzey, daha yaygın ve çirkin olanlara başvuruyorum:

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

Aşağıda, bu çözümü kovalamaktan daha fazla zaman harcayan bazı ek bilgiler verilmiştir:

WindowSoftInputMode hakkında

Farkında olmak için bir başka çekişme noktası daha var. Varsayılan olarak, Android ilk odağı ilk olarak otomatik olarak atar. EditText veya odaklanmış kontrol Activity. Doğal olarak, InputMethod'un (tipik olarak yumuşak klavye) kendini göstererek odak etkinliğine yanıt vereceğini izler. windowSoftInputMode nitelik AndroidManifest.xml, ayarlandığında stateAlwaysHidden, klavyeye bu otomatik olarak atanan ilk odağı görmezden gelmesini bildirir.

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

Neredeyse inanılmaz, klavyenin kontrole dokunduğunuzda açılmasını önlemek için hiçbir şey yapmıyor gibi görünüyor ( focusable="false" ve / veya focusableInTouchMode="false" kontrol için atanır). Görünüşe göre, windowSoftInputMode ayarı, dokunma olaylarından kaynaklanan olayları odaklamak için değil, yalnızca otomatik odaklama olayları için geçerlidir.

Bu nedenle, stateAlwaysHidden ÇOK çok zayıfça adlandırılmış. Belki de çağrılmalı ignoreInitialFocus yerine.

Bu yardımcı olur umarım.


GÜNCELLEME: Pencere belirteci almanın diğer yolları

Odaklanmış bir görünüm yoksa (örneğin parçaları değiştirdiyseniz bile olabilir), kullanışlı bir pencere belirteci sağlayacak başka görünümler vardır.

Bunlar yukarıdaki kod için alternatifler if (view == null) view = new View(activity);  Bunlar sizin faaliyetinize açıkça atıfta bulunmaz.

Bir parça sınıfının içinde:

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

Bir parça verildiğinde fragment bir parametre olarak:

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

İçerik gövdesinden başlayarak:

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

GÜNCELLEME 2: Uygulamayı arka plandan açtığınızda klavyeyi tekrar göstermekten kaçınmak için net netleme

Bu satırı yöntemin sonuna ekleyin:

view.clearFocus();


1024



SoftInputMode'u değiştirmeniz gerektiğini düşünmüyorum. Bu AndroidManifest ayarlarını geçersiz kılacaktır. - Kyle Ivey
Tam cevap için çok teşekkürler. Yumuşak klavye hakkında iyi bir anlayış ile gelmek için bir acemi için yeterli. Klavyeyi fragmandan gizlemek / göstermek istedim ve bu bulduğum en makul cevaptı. - Tina
İyi ve yararlı bir cevap. StackOverflow'ta okumak için bir zevk olan son derece nadir mesajlardan biriydi. - Rameez Hussain
@AlexanderFarber evet, genellikle bir EditTextama görünür olduğuna inanıyorum View çalışacak (ör. TextView), Beri View sadece bir pencere belirteci türetmek için kullanılır (klavyeyi gizlemek için bir şey). Ayrıca, inanıyorum ki View ev sahibinden gelmeli Activity Yerine Fragment - rmirabelle
@rmirabelle bir Fragment öyle görünüyor ki getActivity().getWindow().getDecorView() - McX


Android'i kullanarak sanal klavyeyi gizlemeye zorlayabilirsiniz. InputMethodManager, arayarak hideSoftInputFromWindowOdaklanmış görünümün bulunduğu pencerenin belirtecini geçerek.

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

Bu, klavyenin her durumda gizlenmesini zorlayacaktır. Bazı durumlarda geçmek isteyeceksiniz InputMethodManager.HIDE_IMPLICIT_ONLY Kullanıcı, klavyeyi yalnızca kullanıcı açıkça görünmeye zorlamadığında (menüyü basılı tutarak) gizlediğinizden emin olmak için ikinci parametre olarak.

Not: Bunu Kotlin'de yapmak isterseniz, şunları kullanın: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager


4176



Teşekkürler, ikinci parametre olarak 0 kullanıyorsanız, bu harika çalışıyor gibi görünüyor. Ama eğer InputMethodManager.HIDE_IMPLICIT_ONLY kullanırsam klavye hiç gizlenmez (menüyü basılı tutmama rağmen). Herhangi bir ipucu? - RoflcoptrException
Güzel. Sadece açıklığa kavuşturmak için, bu sadece eğer varsa, onu reddeder ama önlemek haşhaş, değil mi? - Cheezmeister
SoftInput'u gizlemeden önce editText.clearFocus () yöntemini çağırmak yararlı olabilir. - user2224350
çağrı editText.clearFocus() sonra InputMethodManager.HIDE_IMPLICIT_ONLY hatta çalışır 4.1 - sprocket12
Benim için 4.4 / htc üzerinde çalışılan, yürütüyordu View focused = getCurrentFocus() ne olduğunu öğrenmek kesinlikle şu anda odaklanmış görüş focused.clearFocus(), ve sonra inputMethodManager.hideSoftInputFromWindow(focused.getWindowToken(), 0) (açık bayraklarla). - Ionoclast Brigham


Ayrıca yumuşak klavyeyi gizlemek için de kullanışlıdır:

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

Bu, kullanıcı gerçekten editText Görünümü'ne dokunana kadar yazılım tuşlarını basmak için kullanılabilir.


742



Ayrıca, manifestodaki etkinliğinize android: windowSoftInputMode = "stateHidden" ekleyerek aynı efekti elde edebilirsiniz. - BoD
Bunu, API Düzey 9'da bir Fragmentte (sahip olma etkinliğine referans vererek) denedim ve maalesef işe yaramadı. OnResume ve onActivityCreated içinde arama denedim - hiçbir etkisi. - AgentKnopf
Bir diyalogda çalışıyorum ve işe yaradı. Android 3.2 kullanıyorum. OnCreateDialog (Bundle) yöntemine koydum. OnCreate yönteminde çalışmadı. İletişim kutusu iletişim kutusu = super.onCreateDialog (savedInstanceState); dialog.getWindow (). setSoftInputMode (WindowManager.LayoutParams. SOFT_INPUT_STATE_ALWAYS_HIDDEN); Sonuçta içinde EditTexts ile benim görüşüm klavye olmadan ortaya çıkıyor olmasıdır. Kullanıcı bir düzenleme metnine dokunduğunda, klavye açılır. - flobacca
Bu, odak hala bir EditText'te olduğunda (bir düğmeye dokunduktan sonra) çalışmaz. Bunun için Reto'nun çözümünü kullanın. - Noumenon
Bildiri bildirme ayarları niçin kötü bir fikirdir? Bunu bir parçadan arıyorum. Bir parça için geçerli olan açık bir ayar yoktur ... - Greg Ennis


Klavyeyi gizlemek için bir çözüm daha var:

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

Burada geçmek HIDE_IMPLICIT_ONLY pozisyonunda showFlag ve 0 pozisyonunda hiddenFlag. Yumuşak Klavye'yi zorla kapatır.


294



Showflags parametresinde bir gizle bayrağı kullanıyorsunuz. Bu sadece çalışır çünkü sabitler aynı tamsayıları kullanır. Doğru bayrakları kullanarak örnek - Alex
Android 4.0'da test ettim, bu çözümü beğendim çünkü birden fazla düzenleme metnim var.
Bu neden gizlenmişse klavyeyi gösteriyor? :)
@Mark: Yöntem "toggleSoftInput" olarak adlandırıldığından "hideSoftInput" değil :) - Sver
Bu çözüm gizliyse klavyeyi gösterir. Doğru değil - Michael Katkov


Meier'in çözümü benim için de çalışıyor. Benim durumumda benim App üst düzey bir tabHost ve ben sekme geçiş yaparken anahtar kelime gizlemek istiyorum - Ben tabHost View penceresinden belirteç almak.

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

128



Bunu da SearchView ile çalışmak için aldım. Cevabım için aşağıya bakın. Teşekkürler mckoss! - Azurespot


Lütfen aşağıdaki kodu deneyin onCreate()

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

115



Bu yöntem, açıklandığı gibi 2.0 ve 2.1'de "yumuşak klavyeyi gizleyemem" hatasını almanın bir yolu olarak çalışır. code.google.com/p/android/issues/detail?id=7115 ... Ben yukarıda listelenen hideSoftInputFromWindow yöntemi denedim, ancak editView.setInputType (0) did işe yaramadı. - Spike Williams
Bu yöntemi Javadoc (bir hack değil) için yasaldır. editView.setInputType(InputType.TYPE_NULL); - Bostone
Ancak bu çalışır, android: ipucu gizler. Android 1.5 kullanıyorum - Tirtha
@Bostone Bu, SearchView için çalışmıyor - nmxprime
Bu, bir iletişim kutusundan klavyeyi kapatmanız gerektiğinde, bir örneği veya bir öğeyi almanız gerekmediğinde ve kullanıcı iletişim kutusunu kapatan bir düğmeye bastığında bunu tüm düzenleme metinlerine atayabildiğiniz zaman için harikadır. - I'm_With_Stupid


Güncelleştirme: Bu çözümün neden artık işe yaramadığını bilmiyorum (Android 23'te test ettim). Lütfen çözümünü kullanın Saurabh Pareek yerine. İşte burada:

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

Eski cevap:

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

108



Bu kodu nereye yerleştirmeliyim? GetWindow (). SetSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) yapıştırmayı denedim; onCreate () 'da ama klavye asla gizlenmez - user2236096
çalışmaz, radioGroup.setOnCheckedChangeListener, API 23'te test edildi - Christian Schäfer
Daha yakından bakarsanız, InputMethodManager.HIDE_IMPLICIT_ONLY ve InputMethodManager.SHOW_IMPLICIT, "1" ile aynı değere sahiptir, bu nedenle bu çağrılar arasında fark yoktur. => çalışmıyor - Palejandro
imm.toggleSoftInput çağrılırsa (InputMethodManager.HIDE_IMPLICIT_ONLY, 0); sonra klavye ekranda görünecektir :) En iyi uygulama: github.com/ravindu1024/android-keyboardlistener Android SDK'da utanç - Duna
I don't know why this solution is not work any more - Çünkü o AndroidHer şey değişebilir, belki de kısmen kötü bir tasarım ... Dikkatsizce yazarsak, o zaman her şeyi çarçur ederiz ve herşeyi yeniden yazarız. - King King


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

63



Bu benim için çalıştı! Ama neden koydun input.setInputType (0) ? İle etkileşime giremedim EditTextView o kod satırına sahip olduğumda (onu kaldırdığımda çalıştı). - ymerdrengene
@ymerdrengene Haklısın, ben de onu silmek zorunda kaldım. - Lazy


Diğer tüm cevaplar sizin için istediğiniz gibi çalışmazsa, klavyeyi manuel olarak kontrol etmenin başka bir yolu vardır.

Bazılarını yönetecek bir işlev oluşturun. EditTextözellikleri:

public void setEditTextFocus(boolean isFocused) {
    searchEditText.setCursorVisible(isFocused);
    searchEditText.setFocusable(isFocused);
    searchEditText.setFocusableInTouchMode(isFocused);

    if (isFocused) {
        searchEditText.requestFocus();
    }
}

Ardından, EditText klavyeyi açar / kapatırsınız:

searchEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (v == searchEditText) {
            if (hasFocus) {
                // Open keyboard
                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(searchEditText, InputMethodManager.SHOW_FORCED);
            } else {
                // Close keyboard
                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(searchEditText.getWindowToken(), 0);
            }
        }
    }
});

Şimdi, klavyeyi açmak istediğinizde elle ara:

setEditTextFocus(true);

Ve kapanış çağrısı için:

setEditTextFocus(false);

58



+1 - Kapalı bir klavye ile bir aktivite başlatmak istiyorsanız, bu çözümü kullanın ve setEditTextFocus (true) ayarlayan bir onclicklistener ekleyin. Charme gibi çalışıyor! - schlingel
İkinci kod bloğunun 7. ve 10. satırında 'Sembol bağlamını çözemez' var. - gimmegimme
Bunun yerine getContext () kullanın - Rotemmiz


Saurabh Pareek Şimdiye kadar en iyi cevabı var.

Yine de doğru bayrakları kullanabilir.

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

Gerçek kullanım örneği

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

51



2.1'de klavye yine de açılır, sonra gizler. İyi değil. - halxinate
Bu en son sürüm için en verimli olanıdır. Birinin eski sürümler için her zaman ince ayar yapması gerekecektir. Özellikle v3'ten önce. - Alex
GetSystemService () yöntemi Fragments ile çözümlenemiyor! - Mazen Kasser
@Mazen: kullan fragment.getActivity().getSystemService(); - Johan S
Hayır. Samsung Tabamda, Android 5.0, yukarıdaki "klavyeyi koru" kodu, yazılım klavyesi TOGGLE olacak - zaten gizli ise, gösterecektir. Bu işlevin adında TOGGLE bulunmasının bir nedeni var. - ToolmakerSteve