Android yazılım klavyesini kapat / gizle


3819

Düzenimde bir EditTextve bir var Button.

Düzenleme alanına yazıp Buttonsanal klavyeyi gizlemek istiyorum. Bunun basit bir kod parçası olduğunu varsayıyorum, ancak bunun bir örneğini nerede bulabilirim?

Klavyenin dışına dokunduğunuzda.


13
Yalnızca bir EditText ve onay kutuları ve radyolar gibi 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 kaydolursunuz?
AlikElzin-kilaka

14
aptal hissediyorum. Klavyeyi ICS'de gizleyemiyorum. Burada tüm yöntemleri ve bunların kombinasyonlarını denedim. Olmaz. Göstermek için yöntem işe yarıyor, ama hangi windw jetonu, bayrakları gizlemek, herhangi bir aziz için ayar ayarları veya mumlar gizlemek değil. Klavye şovunda her zaman şunu görüyorum: I / LatinIME (396): InputType.TYPE_NULL belirtildi W / LatinIME (396): Beklenmedik giriş sınıfı: inputType = 0x00000000 imeOptions = 0x00000000
13

4
/ ** * Bu yöntem ekran klavyesini gizlemek için kullanılır. * @param etkinlik * / genel void hideSoftKeyboard (Etkinlik etkinliği) {InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService (Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow (activity.getCurrentFocus (). getWindowToken (), 0); }
Harshal Benake

Bu benim için çalıştı
nmxprime

Ekran boyutunu ve çözünürlüğünü artıran cihazlarla sanal klavye gizleme daha az önem kazanıyor.
El-Kathiri Halid

Yanıtlar:


2038

Bu çılgınlığı açıklığa kavuşturmak için, Google'ın yumuşak klavyeye düpedüz saçma tedavisi için tüm Android kullanıcıları adına özür dileyerek başlamak istiyorum. Aynı basit soru için her biri farklı olan birçok cevabın olmasının nedeni, bu API'nin Android'deki diğerleri gibi korkunç bir şekilde tasarlanmış olmasıdır. Bunu açıklamak için kibar bir yol düşünemiyorum.

Klavyeyi gizlemek istiyorum. Ben şu ifadeyle Android'i vermenizi bekliyoruz: Keyboard.hide(). Son. Çok teşekkür ederim. Ancak Android'in bir sorunu var. InputMethodManagerKlavyeyi gizlemek için tuşunu kullanmanız gerekir . Tamam, tamam, bu Android'in klavyenin API'sı. FAKAT! ContextIMM'ye erişmek için bir a'ya sahip olmanız gerekir . Şimdi bir sorunumuz var. Klavyeyi, herhangi bir kullanımı veya ihtiyacı olmayan bir statik veya yardımcı sınıftan gizlemek isteyebilirsiniz Context. veya Ve daha da kötüsü, IMM klavyeyi FROM'dan gizlemek istediğinizi View(veya daha da kötüsünü, ne Window) belirtmenizi gerektirir .

Klavyeyi gizlemeyi bu kadar zorlaştıran şey budur. Sevgili Google: Bir pasta tarifi ararken RecipeProvider, kekin kim tarafından yeneceği VE nerede yenileceği konusunda ilk cevap vermediğim sürece Dünya'da bana tarif vermeyi reddeden hiçbir şey yok !

Bu üzücü hikaye çirkin gerçeklerle bitiyor: Android klavyeyi gizlemek için 2 kimlik biçimi sağlamanız gerekecek: a Contextve a Viewveya a Window.

Ben bir çağrı çağırmak şartıyla ÇOK katı bir şekilde iş yapabilirsiniz statik bir yarar yöntemi oluşturduk 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);
}

Bu yardımcı yöntem SADECE bir den çağrıldığında çalışır unutmayın Activity! Yukarıdaki yöntem , uygun pencere belirtecini getirmek için getCurrentFocushedefi çağırır Activity.

Ama varsayalım ki klavyeyi EditTextbarındırılan bir bilgisayardan gizlemek mi istiyorsunuz DialogFragment? Bunun için yukarıdaki yöntemi kullanamazsınız:

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

Bu işe yaramaz çünkü gösterilirken odaklanmış kontrolü olmayacak olan Fragment'ın ana bilgisayarına bir referans Activitygeçireceksiniz Fragment! Vaov! Bu nedenle, klavyeyi parçalardan gizlemek için daha düşük seviyeli, 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ü kovalayarak daha fazla zaman harcanan bazı ek bilgiler verilmiştir:

WindowSoftInputMode hakkında

Dikkat edilmesi gereken başka bir tartışma konusu daha var. Varsayılan olarak, Android başlangıç ​​odağınızı otomatik olarak ilk EditTextveya odaklanabilir kontrole atar Activity. Doğal olarak, InputMethod'un (genellikle yumuşak klavye) odak olayına kendisini göstererek yanıt vereceğini izler. Olarak ayarlandığında, windowSoftInputModeöznitelik klavyeye otomatik olarak atanan bu başlangıç ​​odağını yoksayması talimatını verir.AndroidManifest.xmlstateAlwaysHidden

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

Neredeyse inanılmaz bir şekilde, kontrole dokunduğunuzda klavyenin açılmasını önlemek için hiçbir şey yapmıyor gibi görünüyor ( focusable="false"ve / veya focusableInTouchMode="false"kontrole atanmadığı sürece ). Görünüşe göre windowSoftInputMode ayarı, dokunma olayları tarafından tetiklenen olaylara odaklanmak için değil, yalnızca otomatik odak olayları için geçerlidir.

Bu nedenle, stateAlwaysHiddengerçekten ÇOK kötü adlandırılmış. Bunun ignoreInitialFocusyerine belki de çağrılmalıdır .

Bu yardımcı olur umarım.


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

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

Bunlar yukarıdaki kodun alternatifleridir. if (view == null) view = new View(activity); Bunlar açıkça etkinliğinizle ilgili değildir.

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

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

fragmentParametre olarak bir parça verildi :

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

İçerik gövdenizden başlayarak:

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

GÜNCELLEME 2: Uygulamayı arka plandan açarsanız klavyenin tekrar gösterilmesini önlemek için net netleme

Bu satırı yöntemin sonuna ekleyin:

view.clearFocus();


2
Çok güzel bir yazı. Bununla birlikte, klavyeyi tetikleyen başka bir etkinlik başlatırsanız, geri döndüğünüzde klavye hala mevcut olacaktır. En iyi etkinlikten çıkarken yönteminizi kullanarak klavyeyi kaldırarak düzeltildi.
Oyvind

3
@rmirabelle Kullanabileceğiniz bir Fragmentşey vargetActivity().getWindow().getDecorView()
McX

1
Bu gönderi harika ama çok önemli iki parçanız yok. Versiyon başına ve imalat başına yapılan küçük değişiklikler. Örneğin, bir Samsung galaxy s6'da klavyeyi gizlemeden önce .clearFocus () kullanmamız gerekir ... değilse, klavye hala düzenleme metninin ikinci tıklamasında görünecektir: S
Warpzit

17
Google gerçekten bu Keyboard.hide();yardımcı programı sağlamalıdır
HendraWD

1
[someView] .getContext () << Etkinlik için durum olabilir. Her zaman aynı nesne. (İç hizmetler hariç ...)
Oliver Dixon

4418

Android'i , odaklanmış görünümünüzü içeren pencerenin belirtecini kullanarak , çağrı yaparak , InputMethodManager'ı kullanarak sanal klavyeyi gizlemeye zorlayabilirsiniz 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);
}

Bu, klavyeyi her durumda gizlenmeye zorlayacaktır. Bazı durumlarda InputMethodManager.HIDE_IMPLICIT_ONLY, klavyeyi yalnızca kullanıcı açıkça görünmeye zorlamadığında (menüyü basılı tutarak) klavyeyi gizlemenizi sağlamak için ikinci parametre olarak geçmek isteyeceksiniz .

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

Kotlin Sözdizimi

// Check if no view has focus:
 val view = this.currentFocus
 view?.let { v ->
  val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager 
  imm?.hideSoftInputFromWindow(v.windowToken, 0)
 }

14
Teşekkürler, bu ikinci parametre olarak 0 kullanılırsa harika çalışıyor gibi görünüyor. Ancak InputMethodManager.HIDE_IMPLICIT_ONLY kullanırsam klavye asla gizlenmez (menüyü basılı tutmama rağmen). İpucu var mı?
RoflcoptrException

27
Güzel. Sadece açıklığa kavuşturmak için, bu sadece mevcutsa reddeder, ancak ortaya çıkmasını engellemez , değil mi?
Cheezmeister

15
SoftInput'u gizlemeden önce editText.clearFocus () öğesini çağırmak yardımcı olabilir
user2224350

111
editText.clearFocus()Sonra arama InputMethodManager.HIDE_IMPLICIT_ONLYbile çalışıyor4.1
sprocket12

11
4.4 / htc'de benim için çalışan View focused = getCurrentFocus(), kesinlikle o anda odaklanmış görüş, arama focused.clearFocus()ve ardından inputMethodManager.hideSoftInputFromWindow(focused.getWindowToken(), 0)(açık bayraklarla) olanı elde etmek için yürütüyordu .
Ionoclast Brigham

806

Yazılım klavyesini gizlemek için de yararlıdır:

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

Bu, kullanıcı editText Görünümüne gerçekten dokunana kadar ekran klavyesini bastırmak için kullanılabilir.


116
Manifestteki aktivitenize android: windowSoftInputMode = "stateHidden" ekleyerek de aynı efekti elde edebilirsiniz.
BoD

7
Bunu, API Düzey 9'daki bir Parçada (sahip olma etkinliğine referansla) denedim ve maalesef işe yaramadı. OnResume ve onActivityCreated olarak adlandırmayı denedim - hiçbir etkisi yok.
AgentKnopf

2
Bir iletişim kutusunda çalışıyorum ve bu işe yaradı. Android 3.2 kullanıyorum. Ben onCreateDialog (Bundle) yöntemine koydu. 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ç olarak içinde EditTexts ile benim görünüm klavye olmadan görünür olmasıdır. Kullanıcı bir düzenleme metnine dokunduğunda, klavye görünür.
flobacca

4
Odak hala bir EditText'te olduğunda işe yaramaz (bir düğmeye dokunduktan sonra olduğu gibi). Bunun için Reto'nun çözümünü kullanın.
Noumenon

4
Manifest ayarlarını geçersiz kılmak neden kötü bir fikir? Bunu bir parçadan arıyorum. Bir parça için geçerli bir belirti ayarı yok ...
Greg Ennis

349

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

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

İşte geçmesi HIDE_IMPLICIT_ONLYkonumunda showFlagve 0pozisyonunda hiddenFlag. Yumuşak Klavyeyi zorla kapatacaktır.


4
Showflags parametresinde bir gizleme bayrağı kullanıyorsunuz. Bu yalnızca sabitler aynı tamsayıları kullandığından çalışır. Doğru bayrakları kullanan örnek
Alex

Android 4.0 üzerinde test edildi, bu çözümü beğendim, çünkü birden fazla düzenleme metni, o etkinliğe odaklanabilecek düğmeler var

32
@Mark: Yöntem "toggleSoftInput" olarak adlandırıldığından, "hideSoftInput" değil ":)
Sver

19
Bu çözüm gizliyse klavyeyi gösterir. Doğru değil
Michael Katkov

1
@AkashAggarwal - Klavye gösterdiği için sadece sizin için çalıştığını görmezden gelirseniz "çalışır". (Klavyenin görünürlüğünü TOGGLES: gösterildiğinde gizler, ancak gizlendiğinde gösterir !!) Her koşulda, tüm cihazlarda, Android'in gelecekteki tüm sürümleri için klavyenin OLMAYACAĞINI GARANTİ ETEBİLİRSİNİZ Bunu aradığın zaman gösteriliyor mu? Öyleyse, devam edin ve kullanın!
ToolmakerSteve

149

Meier'in çözümü de benim için çalışıyor. Benim durumumda Uygulamamın üst seviyesi bir tabHost ve sekmeleri değiştirirken anahtar kelimeyi gizlemek istiyorum - tabHost View'dan pencere belirtecini alıyorum.

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

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

139

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

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

2
Bu yöntem, code.google.com/p/android/issues/detail?id=7115 ... hideSoftInputFromWindow yönteminde açıklandığı gibi 2.0 ve 2.1'deki "yumuşak klavye gizlenemiyor" hatasını gidermenin bir yolu olarak çalışır. yukarıda listelenen ben denedim, ama editView.setInputType (0) işe yaramadı.
Spike Williams

18
Bu yöntemi yeniden yazmak istiyorum olsa da Javadoc (bir kesmek değil) başına okunaklıeditView.setInputType(InputType.TYPE_NULL);
Bostone

3
ancak bu çalışır, android gizler: ipucu. Android 1.5 kullanıyorum
Tirtha

Bu, klavyeyi bir iletişim kutusundan kapatmanız gerektiğinde, bir örnek veya herhangi bir şey almanıza gerek olmadığında ve kullanıcı iletişim kutusunu kapatan bir düğmeye bastığında bunu tüm düzenleme metinlerine atayabileceğiniz zamanlar için
harikadır

Çalışır, ancak imleci de gizler. İmlece ihtiyacım var ama sistem klavyesine gerek yok.
Stefan Brendle

129

Güncelleme: Bu çözümün neden artık işe yaramadığını bilmiyorum (Android 23'te test ettim). Lütfen bunun yerine Saurabh Pareek'in çözümünü kullanın. İş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);

8
Bu kodu nereye yerleştirmeliyim? GetWindow () yapıştırmaya çalıştım. SetSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); onCreate () ama klavye asla gizli değil
user2236096

çalışmıyor, radioGroup.setOnCheckedChangeListener, API 23 adresinde test edilmiştir
Christian Schäfer

Daha yakından bakarsanız, InputMethodManager.HIDE_IMPLICIT_ONLY ve InputMethodManager.SHOW_IMPLICIT aynı değere sahiptir, bu değer "1" dir, bu nedenle bu çağrılar arasında fark yoktur. => çalışmıyor
Palejandro

imm.toggleSoftInput (InputMethodManager.HIDE_IMPLICIT_ONLY, 0) çağrılırsa; o zaman klavye ekranda gösterilecek :) 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- Android olduğu için , her şey değişebilir, belki de kısmen kötü tasarımdan ... Dikkatsizce yazıyoruz, sonra hepsini dışarı atıyoruz ve her şeyi yeniden yazıyoruz.
Kral Kral

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

5
Bu benim için çalıştı! Ancak input.setInputType (0) 'ı neden koydunuz ? Bu kod satırı vardı (ben kaldırdığımda çalıştı) EditTextView ile etkileşim olamazdı .
ymerdrengene

Muhtemelen input.getContext().getSystemService(Context.INPUT_METHOD_SERVICE).
CoolMind

input.setInputType(0);Bu koddan kaldırdım . Bu bir klavye davranışı ve değiştirilemez inputTypeiçin EditText.
CoolMind

74

Buradaki diğer tüm yanıtlar sizin istediğiniz şekilde çalışmazsa, klavyeyi manuel olarak kontrol etmenin başka bir yolu vardır.

Bazı EditTextözelliklerini yönetecek bir işlev oluşturun :

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

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

Ardından, EditTextklavyeyi açtığınızdan / kapattığınızdan emin olun :

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 manuel olarak açmak istediğinizde şunu arayın:

setEditTextFocus(true);

Ve aramayı kapatmak için:

setEditTextFocus(false);

+1 - Kapalı klavye ile bir etkinlik başlatmak istiyorsanız bu çözümü kullanın ve setEditTextFocus (true) ayarını yapan bir onclicklistener ekleyin. Charme gibi çalışır!
schlingel

İkinci kod bloğunun 7. ve 10. satırında 'Sembol bağlamı çözülemiyor' var.
gimmegimme

Bunun yerine getContext () kullanın
Rotemmiz

61

Saurabh Pareek şimdiye kadarki en iyi cevaba sahip.

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

1
Bu en son sürüm için en verimlidir. Birinin her zaman eski sürümler için ayarlanması gerekir. Özellikle v3'ten önce.
Alex

2
@Mazen: kullanımfragment.getActivity().getSystemService();
Johan S

Bu, hem gösteriyi hem de gizlemeyi kapsayan en kapsamlı cevaptır.
André Staltz

4
Hayır. Samsung Tab'ımda, Android 5.0, Yukarıdaki "klavyeyi gizle" kodu, yumuşak klavyeyi TOGGLE (zaten gizli ise) gösterecektir. Bu işlevin adında TOGGLE olması için bir neden vardır.
ToolmakerSteve

57

aradığımdan, burada benim için çalışan bir cevap buldum

// 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 5.1 ile bir Motorola için benim için çalışan tek kişi
GMX

55

Kısa cevap

Sizin de OnClickdinleyici çağrı onEditorActionarasında EditTextolanIME_ACTION_DONE

button.setOnClickListener(new OnClickListener() {

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

Detaylandırma

Bu yöntemin Android'in tasarım modeliyle daha iyi, daha basit ve daha uyumlu olduğunu hissediyorum. Yukarıdaki basit örnekte (ve genellikle yaygın vakaların çoğunda) EditText, odaklanmış / odaklanmış bir tane olacaktır ve genellikle klavyeyi ilk etapta çağıran kişidir (kesinlikle birçoğunda çağırabilir. ortak senaryolar). Aynı şekilde, bu klavyeyi serbest bırakmak için biri olmalıdır, genellikle bu bir yapılabilir ImeAction. Sadece nasıl bir bakınız EditTextile android:imeOptions="actionDone", aynı yollarla aynı davranışı elde etmek istiyoruz davranır.


Bu ilgili cevabı kontrol et


Cevap bu. Yalnızca çapraz sürümde çalışan yöntem. Bu soruyu göndermek için bu soruya geri döndüm çünkü kimsenin tanımadığını düşünmedim
Noah Passalacqua

Bu doğru cevap olmalı. Android'i gerçekten orada olması gerektiğinde klavyeyi gizlemek yerine kandırmak yerine, kullanıcının yapıldığını söyleriz, bu da kullanıcının klavyede "YAPILDI" yı tıklamış gibi aynı ImeAction [aptal adı, itiraf] tetikler . Bu şekilde, kullanıcı klavyedeki girişi onaylarsa veya UI düğmesine dokunursa hiçbir şey fark etmez.
Oliver Hausler

46

Bu çalışmalı:

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

Klavye gizlenmiş olsa bile kısmen çalıştı "isActive ()" yanlış döndürür!
xpto

Tabii ki, olması gerekiyordu. Ya da belki seni anlamıyorum. Her neyse, sınıfa ne zaman ve ne zaman gösterilmemesi gerektiği konusunda daha fazla kontrol sahibi olmak için yöntemleri hide()ve show()yöntemleri tamamlayabilirsiniz . Benim için çalışıyor, ben de yaptım :) Örneği düzenleyeceğim
slinden77

@YoushaAleayoub evet olacak. KeyBoard.toggle(fragment.getActivity())
slinden77

@ slinden77, lol, Cevabınızdan bahsediyorum ... yorumladığınız bu değil. Yani bu cevap hala işe yaramaz.
Yousha Aleayoub

@YoushaAleayoub uhm evet olacak. Orijinal soru parçalardan bahsetmiyor, parçalardan bahseden sizsiniz. Bu yüzden cevabım son derece geçerli. Parçalarla kullanmak için, yöntemi Fragmenta yorumundan farklı bir şekilde çağırın . Lütfen yöntemleri nasıl kullanacağınızı öğrenin ve sonra tekrar gelin. İnsanları aptalca cevaplarınızla karıştırıyorsunuz
slinden77

43

Bir Hex numarası girmek için özel bir klavye kullanıyorum, bu yüzden IMM klavyesinin görünmesini sağlayamıyorum ...

V3.2.4_r1'de setSoftInputShownOnFocus(boolean show), hava durumunu kontrol etmek veya bir TextView odaklandığında klavyeyi görüntülememek için eklendi, ancak hala gizli olduğundan yansıma kullanılmalıdır:

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

Eski sürümler için, a ile çok iyi sonuçlar aldım (ama mükemmel olmaktan uzak) OnGlobalLayoutListener, ViewTreeObserverkök görünümümden bir a yardımı ile ekledim ve sonra klavyenin böyle gösterilip gösterilmediğini kontrol ettim:

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

Bu son çözüm, klavyeyi bir anlığına gösterebilir ve seçim tutamaçlarını karıştırır.

Klavyede tam ekran olduğunda, onGlobalLayout çağrılmaz. Bundan kaçınmak için TextView # setImeOptions (int) veya TextView XML bildiriminde kullanın:

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

Güncelleme: Diyalogların klavyeyi asla göstermemek için kullandığı ve tüm sürümlerde çalıştığı bulundu:

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

Teşekkür ederim. İki bayrak FLAG_ALT_FOCUSABLE_IM ve FLAG_ALT_FOCUSABLE_IM benim durumumda yardımcı olan tek şey. Etkinliğimde bir klavyenin gösterilmesini istemedim - kullanıcı bir düzenleme metnini tıklattığında bile. (Kendi "tuş takımımı" oluşturdum).
Daniel Novak

Serin çözüm, ancak ön etkinliğiniz tam ekran değilse, klavye arkasında görünür. Ayrıca klavyenin imleç hareket yardımı da hala görülebilir. Ve bu da tenli değil.
Mart'ta

İkinci olarak. Tüm olası yollardan sadece getWindow (). SetFlags () yöntemi, en azından stok Android 5.1'de çalışır. En azından kullanıcı alana dokunduğunda, setSoftInputShownOnFocus () ayarının artık setShowSoftInputOnFocus () olduğuna ve artık gizlenmediğine, ancak çalışmadığına dikkat edin.
olefevre

"Güncellemen" benim için tek çalışan çözümdü. En az iki saat bir çözüm arıyorum :)
Stefan Brendle

33
public void setKeyboardVisibility(boolean show) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if(show){
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    }else{
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0);
    }
}

30

Ben iş parçacığı yayınlanan tüm çözümler üzerinde çalışmak için iki günden fazla geçirdim ve onları bir şekilde eksik bulundu. Tam gereksinimim,% 100 güvenilirlik ile ekran klavyesini gösterecek veya gizleyecek bir düğmeye sahip olmak. Klavye gizli durumundayken, kullanıcının hangi giriş alanlarını tıklattığına bakılmaksızın yeniden görünmemelidir. Görünür durumundayken, kullanıcının tıkladığı düğmelerden bağımsız olarak klavye kaybolmamalıdır. Bunun en yeni cihazlara kadar Android 2.2 ve üzeri sürümlerde çalışması gerekir.

Benim app temiz RPN bu çalışan bir uygulama görebilirsiniz .

Birkaç farklı telefonda (froyo ve zencefilli cihazlar dahil) önerilen cevapların birçoğunu test ettikten sonra, android uygulamalarının güvenilir bir şekilde yapabileceği ortaya çıktı:

  1. Klavyeyi geçici olarak gizleyin. Bir kullanıcı yeni bir metin alanına odaklandığında tekrar görünecektir.
  2. Etkinlik başladığında klavyeyi gösterin ve etkinlik üzerinde klavyenin her zaman görünür olması gerektiğini belirten bir bayrak ayarlayın. Bu bayrak yalnızca bir etkinlik başlatılırken ayarlanabilir.
  3. Klavyeyi asla göstermeyecek veya kullanılmasına izin vermeyecek bir etkinlik işaretleyin. Bu bayrak yalnızca bir etkinlik başlatılırken ayarlanabilir.

Benim için klavyeyi geçici olarak gizlemek yeterli değil. Bazı cihazlarda, yeni bir metin alanı odaklanır odaklanmaz yeniden görünecektir. Uygulamam bir sayfada birden çok metin alanı kullandığından, yeni bir metin alanına odaklanmak gizli klavyenin tekrar açılmasına neden olur.

Maalesef listedeki 2. ve 3. maddeler yalnızca bir etkinlik başlatıldığında güvenilirlik sağlar. Etkinlik görünür hale geldiğinde klavyeyi kalıcı olarak gizleyemez veya gösteremezsiniz. İşin püf noktası, kullanıcı klavye değiştirme düğmesine bastığında etkinliğinizi yeniden başlatmaktır. Uygulamamda kullanıcı seçim klavyesi düğmesine bastığında, aşağıdaki kod çalışır:

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

Bu, geçerli etkinliğin durumunun bir Pakete kaydedilmesine neden olur ve ardından klavyenin gösterilmesi veya gizlenmesi gerektiğini belirten bir boole içinden geçen etkinlik başlatılır.

OnCreate yönteminin içinde aşağıdaki kod çalıştırılır:

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

Yazılım klavyesi gösterilmesi gerekiyorsa, InputMethodManager'a klavyeyi göstermesi söylenir ve pencereye yazılım girişini her zaman görünür yapması söylenir. Yazılım klavyesi gizlenecekse, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM ayarlanır.

Bu yaklaşım, test ettiğim tüm cihazlarda güvenilir bir şekilde çalışır - android 2.2 çalıştıran 4 yaşındaki bir HTC telefondan 4.2.2 çalıştıran bir nexus 7'ye kadar. Bu yaklaşımın tek dezavantajı, geri düğmesini tutarken dikkatli olmanızdır. Benim app aslında sadece bir ekran (onun bir hesap makinesi) olduğu gibi onBackPressed () geçersiz kılabilir ve cihazların ana ekranına dönebilirsiniz.


1
Ayrıntılı bir çözüm, ancak bence çok fazla şey var, sadece binlerce nesneyi yeniden klavyeyi gizlemek için yeniden oluşturmak. Android için IMM'yi kimin tasarladığını bilmiyorum, ancak bir Windows APi gibi kokuyor. Bence, iyi bir IME'nin iki yöntemi olmalı: sakla ve göster :-)
rupps

Tüm doğru, ama benim geçici çözüm bir avantajı var - her zaman çalışır! Kullanıcı arayüzündeki hangi alanların odağa sahip olduğuna, kullanıcının geçiş yapmak ve klavyeye ne yaptığını ve Android'in hangi sürümünü çalıştırdığına bakılmaksızın, klavyeyi her zaman değiştirecek başka bir çözüm bulamıyorum: - \
Luke Sleeman

Adamım, klavyeyi saklamaktan tamamen çaresizim. Binlerce şey denedim ve noooone çalışır. Ama geçici çözümün benim için çok fazla, 10 parça gibi yeniden oluşturmak, hizmetleri başlatmak, WeakReferences çok silmek zorunda .... biliyor musunuz? GC sadece 25mb gibi atıyor: S ... Hala bunu yapmak için güvenilir bir yol arıyor :(
rupps

@Dmitry iyi bir merhaba dünya değil ... tabletler için karmaşık bir uygulamadır. Ben sadece aptal bir klavyeyi gizlemek için tamamen bellekten boşaltmayı reddediyorum ... Neyse burada önerilen bin çözümleri birleştiren bir şey buldum :)
rupps

27

Tüm bu çözümlere alternatif olarak , klavyeyi açmak için kullanılan (EditText) alanına başvuru yapmadan yumuşak klavyeyi herhangi bir yerden kapatmak istiyorsanız , ancak alan odaklanmışsa yine de yapmak istediyseniz, bu (bir Faaliyetten):

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

25

Sayesinde bu SO cevap , bir ViewPager fragmanları ilerlerken benim durumumda, güzel işleri, aşağıdakileri türetilmiş ...

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

21

Yukarıdaki yanıtlar farklı senaryolar için geçerlidir, ancak klavyeyi bir görünüm içinde gizlemek ve doğru içeriği elde etmek için mücadele etmek istiyorsanız şunu deneyin:

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

ve bağlamın yapıcıdan getirilmesi için :)

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

18

Bir birim veya işlev testi sırasında yazılım klavyesini kapatmak istiyorsanız, testinizdeki "geri düğmesini" tıklatarak bunu yapabilirsiniz:

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

Yukarıdaki onBackPressed()söz konusu Faaliyet için tetiklemediğinden, "geri düğmesi" ni tırnak içine aldım . Sadece klavyeyi kapatır.

Devam etmeden önce bir süre duraklattığınızdan emin olun, çünkü geri düğmesinin kapatılması biraz zaman alır, bu nedenle sonraki Görünümler vb. Tıklamaları kısa bir duraklamadan sonra (1 saniye yeterince uzun ime) ).


16

Android için Mono'da (AKA MonoDroid) bunu nasıl yapacağınız aşağıda açıklanmıştır

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

1
searchboxParçacıkta neler var ?
PCoder

16

Bu, tüm tuhaf klavye davranışları için benim için çalıştı

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

1
Bundan önce 10 cevap denediğimi düşün. Umut vermişti. Teşekkürler dostum.
Bolling

MRootView nedir?
justdan0227

14

android:windowSoftInputMode="stateHidden"Manifest dosyasındaki etkinliğinize ekleyin . Misal:

<activity
            android:name=".ui.activity.MainActivity"
            android:label="@string/mainactivity"
            android:windowSoftInputMode="stateHidden"/>

14

Basit ve kullanımı kolay yöntem, sadece hideKeyboardFrom'u (YourActivity.this) arayın ; klavyeyi gizlemek

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

13

Bu optimize edilmiş kodu etkinliğinizde kullanmanız yeterlidir:

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

İyi çalışıyor. Teşekkürler
Alif

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

onTouchListener'ı çağırdıktan sonra:

findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Utils.hideSoftKeyboard(activity);
        return false;
    }
});

Bunu da deneyin - bu benim için çalıştı: InputMethodManager imm = ((InputMethodManager) getSystemService (Activity.INPUT_METHOD_SERVICE)); imm.hideSoftInputFromWindow (getWindow (). getCurrentFocus (). getWindowToken (), 0);
zmicer

12

bunu kullan

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

12

Benim durumum için, eylem çubuğundaki bir SearchView kullanıyordum. Kullanıcı bir arama yaptıktan sonra klavye tekrar açılır.

InputMethodManager kullanımı klavyeyi kapatmadı. ClearFocus ve arama görünümünün odaklanabilir ayarını false olarak ayarladım:

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

1
Çok zeki. Kullanıcı başka bir arama isterse, tekrar ara düğmesini tıklamanız yeterlidir.
Alex

SearchView clearFocus(), Android API sayfalarında a içermez , bu yüzden bu benim için işe yaramadı, ancak başka bir çözüm işe yaradı (aşağıdaki cevabıma bakın).
Azurespot


12

Davam da var, burada EditTextda bir yerde bulunabilir AlertDialog, böylece klavye kapatıldığında kapatılmalıdır. Aşağıdaki kod herhangi bir yerde çalışıyor gibi görünüyor:

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

1
HideSoftInputFromWindow () yöntemine hangi EditText parametresi geçirdiğini denetlemeniz gerekmediğinden bu çözüm daha iyidir. Harika çalışıyor !!
Billyjoker

12

Neredeyse tüm bu cevapları denedim, özellikle samsung galaxy s5 ile ilgili bazı rastgele sorunlar yaşadım.

Sonunda şovu ve gizlemeyi zorlamak ve mükemmel çalışıyor:

/**
 * 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);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.