Tutup / sembunyikan keyboard lunak android

3819

Saya memiliki EditTextdan Buttondalam tata letak saya.

Setelah menulis di bidang edit dan mengklik Button, saya ingin menyembunyikan keyboard virtual. Saya berasumsi bahwa ini adalah potongan kode yang sederhana, tetapi di mana saya dapat menemukan contohnya?

Saat menyentuh di luar keyboard.

Ak23
sumber
13
Bagaimana jika Anda hanya memiliki satu EditText dan beberapa tombol, seperti kotak centang dan radio? Satu-satunya tempat Anda memerlukan keyboard adalah dalam EditText tunggal. Bagaimana Anda mendaftar untuk mengetahui bahwa sesuatu yang lain telah dipilih / diklik untuk menyembunyikan keyboard?
AlikElzin-kilaka
14
aku merasa bodoh. Saya tidak dapat menyembunyikan keyboard di ICS. Mencoba semua metode di sini dan kombinasi mereka. Tidak mungkin. Metode untuk menunjukkan itu bekerja, tapi saya tidak bisa menyembunyikannya tidak peduli apa pun windw token, menyembunyikan bendera, pengaturan manifes atau lilin untuk setiap orang kudus. Pada acara keyboard saya selalu melihat ini: I / LatinIME (396): InputType.TYPE_NULL ditentukan W / LatinIME (396): Kelas input yang tidak terduga: inputType = 0x00000000 imeOptions = 0x00000000
rupps
4
/ ** * Metode ini digunakan untuk menyembunyikan keyboard lunak. * @param aktivitas * / public void hideSoftKeyboard (Aktivitas aktivitas) {InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService (Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow (activity.getCurrentFocus (). getWindowToken (), 0); }
Harshal Benake
ini bekerja untuk saya
nmxprime
Dengan perangkat yang meningkatkan ukuran dan resolusi layar, menyembunyikan keyboard virtual menjadi kurang penting.
Al-Kathiri Khalid

Jawaban:

2038

Untuk membantu memperjelas kegilaan ini, saya ingin memulai dengan meminta maaf atas nama semua pengguna Android atas perlakuan konyol Google terhadap keyboard lunak. Alasan ada begitu banyak jawaban, masing-masing berbeda, untuk pertanyaan sederhana yang sama adalah karena API ini, seperti banyak lainnya di Android, dirancang dengan mengerikan. Saya tidak bisa memikirkan cara yang sopan untuk menyatakannya.

Saya ingin menyembunyikan keyboard. Saya berharap untuk memberikan Android dengan pernyataan berikut: Keyboard.hide(). Tamat. Terima kasih banyak. Tapi Android punya masalah. Anda harus menggunakan InputMethodManageruntuk menyembunyikan keyboard. OKE, baiklah, ini adalah API Android untuk keyboard. TAPI! Anda harus memiliki Contextuntuk mendapatkan akses ke IMM. Sekarang kita punya masalah. Saya mungkin ingin menyembunyikan keyboard dari kelas statis atau utilitas yang tidak memiliki kegunaan atau kebutuhan apa pun Context. atau Dan JAUH lebih buruk, IMM mengharuskan Anda menentukan apa View(atau bahkan lebih buruk, apa Window) yang ingin Anda sembunyikan dari keyboard.

Inilah yang membuat menyembunyikan keyboard sangat menantang. Dear Google: Ketika saya mencari resep kue, tidak ada RecipeProviderdi Bumi yang akan menolak untuk memberi saya resep kecuali saya pertama kali menjawab SIAPA kue itu akan dimakan oleh DAN di mana ia akan dimakan !!

Kisah sedih ini berakhir dengan kebenaran yang buruk: untuk menyembunyikan keyboard Android, Anda akan diminta untuk memberikan 2 bentuk identifikasi: a Contextdan salah satu Viewatau a Window.

Saya telah membuat metode utilitas statis yang dapat melakukan pekerjaan SANGAT solid, asalkan Anda menyebutnya dari sebuah 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);
}

Ketahuilah bahwa metode utilitas ini HANYA berfungsi saat dipanggil dari Activity! Metode di atas memanggil getCurrentFocustarget Activityuntuk mengambil token jendela yang tepat.

Tapi misalkan Anda ingin menyembunyikan keyboard dari EditTexthost di DialogFragment? Anda tidak dapat menggunakan metode di atas untuk itu:

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

Ini tidak akan berhasil karena Anda akan memberikan referensi ke Fragmenthost 's Activity, yang tidak akan memiliki kontrol terfokus saat Fragmentditampilkan! Wow! Jadi, untuk menyembunyikan keyboard dari fragmen, saya beralih ke level yang lebih rendah, lebih umum, dan lebih jelek:

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

Di bawah ini adalah beberapa informasi tambahan yang diperoleh dari semakin banyak waktu yang terbuang mengejar solusi ini:

Tentang windowSoftInputMode

Masih ada hal lain yang perlu diperhatikan. Secara default, Android akan secara otomatis menetapkan fokus awal ke EditTextkontrol pertama atau yang dapat fokus di Activity. Secara alami, InputMethod (biasanya keyboard lunak) akan merespons acara fokus dengan menunjukkan dirinya. The windowSoftInputModeatribut dalam AndroidManifest.xml, ketika diatur ke stateAlwaysHidden, menginstruksikan keyboard untuk mengabaikan fokus awal ini secara otomatis ditugaskan.

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

Hampir tidak dapat dipercaya, tampaknya tidak melakukan apa pun untuk mencegah keyboard membuka ketika Anda menyentuh kontrol (kecuali focusable="false"dan / atau focusableInTouchMode="false"ditugaskan ke kontrol). Rupanya, pengaturan windowSoftInputMode hanya berlaku untuk acara fokus otomatis, bukan untuk memfokuskan acara yang dipicu oleh acara sentuh.

Oleh karena itu, stateAlwaysHiddenmemang SANGAT buruk namanya. Mungkin seharusnya disebut ignoreInitialFocussebaliknya.

Semoga ini membantu.


PEMBARUAN: Lebih banyak cara untuk mendapatkan token jendela

Jika tidak ada tampilan terfokus (mis. Bisa terjadi jika Anda baru saja mengubah fragmen), ada tampilan lain yang akan menyediakan token jendela yang bermanfaat.

Ini adalah alternatif untuk kode di atas. if (view == null) view = new View(activity); Ini tidak merujuk secara eksplisit ke aktivitas Anda.

Di dalam kelas fragmen:

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

Diberikan fragmen fragmentsebagai parameter:

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

Mulai dari badan konten Anda:

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

UPDATE 2: Hapus fokus untuk menghindari menampilkan keyboard lagi jika Anda membuka aplikasi dari latar belakang

Tambahkan baris ini ke akhir metode:

view.clearFocus();

rmirabelle
sumber
2
Langgan yang sangat bagus. Namun satu hal, jika Anda memulai aktivitas lain di atasnya, yang memicu keyboard, keyboard akan tetap ada ketika Anda kembali. Memperbaiki itu dengan menghapus keyboard menggunakan metode Anda saat keluar dari aktivitas teratas.
Oyvind
3
@rabelabelle Dalam Fragmenttampaknya Anda dapat menggunakangetActivity().getWindow().getDecorView()
McX
1
Posting ini bagus tetapi Anda tidak memiliki dua bagian yang sangat penting. Perubahan halus dilakukan per versi dan dilakukan per pembuatan. Misalnya pada Samsung galaxy s6 kita perlu menggunakan .clearFocus () sebelum menyembunyikan keyboard ... jika tidak, keyboard akan tetap muncul pada klik kedua dari edittext: S
Warpzit
17
google seharusnya benar-benar menyediakan Keyboard.hide();utilitas itu
HendraWD
1
[someView] .getContext () << Dapat sesuai aktivitas. Itu objek yang sama selalu. (Kecuali layanan di dalam ...)
Oliver Dixon
4419

Anda dapat memaksa Android untuk menyembunyikan keyboard virtual menggunakan InputMethodManager , memanggil hideSoftInputFromWindow, meneruskan token jendela yang berisi tampilan fokus Anda.

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

Ini akan memaksa keyboard disembunyikan di semua situasi. Dalam beberapa kasus, Anda akan ingin InputMethodManager.HIDE_IMPLICIT_ONLYmemasukkan sebagai parameter kedua untuk memastikan Anda hanya menyembunyikan keyboard ketika pengguna tidak secara paksa memaksanya untuk muncul (dengan menahan menu).

Catatan: Jika Anda ingin melakukan ini di Kotlin, gunakan: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

Sintaks Kotlin

// 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)
 }
Reto Meier
sumber
14
Terima kasih ini tampaknya bekerja dengan baik jika menggunakan 0 sebagai parameter kedua Tetapi jika saya menggunakan InputMethodManager.HIDE_IMPLICIT_ONLY keyboard tidak pernah disembunyikan (meskipun saya tidak menekan menu). Ada petunjuk?
RoflcoptrException
27
Keren. Hanya untuk memperjelas, ini hanya menolaknya jika ada, tetapi tidak akan mencegahnya muncul, bukan?
Cheezmeister
15
Mungkin bermanfaat untuk memanggil editText.clearFocus () sebelum menyembunyikan softInput
user2224350
111
Memanggil editText.clearFocus()kemudian InputMethodManager.HIDE_IMPLICIT_ONLYbekerja pada4.1
sprocket12
11
Apa yang bekerja untuk saya pada 4.4 / htc adalah mengeksekusi View focused = getCurrentFocus()untuk mendapatkan apa yang jelas - jelas merupakan tampilan fokus, panggilan focused.clearFocus(), dan kemudian inputMethodManager.hideSoftInputFromWindow(focused.getWindowToken(), 0)(dengan flag yang jelas).
Ionoclast Brigham
806

Juga berguna untuk menyembunyikan soft-keyboard adalah:

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

Ini dapat digunakan untuk menekan keyboard lunak hingga pengguna benar-benar menyentuh tampilan editText.

Garnet Ulrich
sumber
116
Anda juga dapat mencapai efek yang sama dengan menambahkan android: windowSoftInputMode = "stateHidden" pada aktivitas Anda di manifes.
BoD
7
Mencoba ini dalam Fragmen (merujuk aktivitas pemilik) di API Level 9 dan sayangnya tidak berhasil. Sudah mencoba menyebutnya di onResume dan onActivityCreated - tidak ada efek.
AgentKnopf
2
Saya sedang mengerjakan dialog dan ini berhasil. Saya menggunakan Android 3.2. Saya memasukkannya ke dalam metode onCreateDialog (Bundle). Itu tidak berfungsi dalam metode onCreate. Dialog dialog = super.onCreateDialog (disimpanInstanceState); dialog.getWindow (). setSoftInputMode (WindowManager.LayoutParams. SOFT_INPUT_STATE_ALWAYS_HIDDEN); Hasilnya adalah tampilan saya dengan EditTexts di dalamnya muncul tanpa keyboard. Ketika pengguna menyentuh teks edit, keyboard muncul.
flobacca
4
Ini tidak berfungsi ketika fokus masih dalam EditText (seperti, setelah menyentuh tombol). Gunakan solusi Reto untuk itu.
Noumenon
4
Mengapa mengesampingkan pengaturan nyata merupakan ide yang buruk? Saya menyebut ini dari sebuah fragmen. Tidak ada pengaturan manifes yang berlaku untuk sebuah fragmen ...
Greg Ennis
349

Saya punya satu solusi lagi untuk menyembunyikan keyboard:

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

Di sini lewat HIDE_IMPLICIT_ONLYdi posisi showFlagdan 0di posisi hiddenFlag. Ini akan menutup paksa Keyboard lunak.

Saurabh Pareek
sumber
4
Anda menggunakan bendera sembunyikan di parameter showflags. Ini hanya berfungsi karena konstanta menggunakan bilangan bulat yang sama. Contoh menggunakan flag yang benar
Alex
diuji pada Android 4.0, saya suka solusi ini, karena saya memiliki beberapa teks edit, tombol pada aktivitas itu, yang dapat memiliki fokus
32
@ Mark: Karena metode ini disebut "toggleSoftInput", bukan "hideSoftInput" :)
Sver
19
Solusi ini menunjukkan keyboard jika disembunyikan. Itu tidak benar
Michael Katkov
1
@AkashAggarwal - Ini "berfungsi" jika Anda mengabaikan fakta bahwa itu hanya bekerja untuk Anda karena keyboard ditampilkan. (Ini TOGGLES visibilitas keyboard: ia menyembunyikan ketika ditampilkan, TAPI itu menunjukkan ketika itu tersembunyi !!) Dapatkah Anda MENJAMIN bahwa dalam semua keadaan, pada semua perangkat, untuk semua versi Android masa depan, bahwa keyboard TIDAK akan ditampilkan pada saat Anda memanggil ini? Jika demikian, maka maju dan gunakan!
ToolmakerSteve
149

Solusi Meier juga bekerja untuk saya. Dalam kasus saya, tingkat teratas Aplikasi saya adalah tabHost dan saya ingin menyembunyikan kata kunci saat berpindah tab - saya mendapatkan token jendela dari Tampilan tabHost.

tabHost.setOnTabChangedListener(new OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(tabHost.getApplicationWindowToken(), 0);
    }
}
mckoss
sumber
Saya punya ini untuk bekerja dengan SearchView juga. Lihat di bawah untuk jawaban saya. Terima kasih mckoss!
Azurespot
139

Silakan coba kode di bawah ini onCreate()

EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);
Jeyavel
sumber
2
Metode ini berfungsi sebagai sarana untuk mengatasi bug "tidak dapat menyembunyikan keyboard lunak" pada 2.0 dan 2.1 seperti yang dijelaskan dalam code.google.com/p/android/issues/detail?id=7115 ... metode hideSoftInputFromWindow yang tercantum di atas tidak berfungsi ketika saya mencobanya, tetapi editView.setInputType (0) berhasil.
Spike Williams
18
Ini sah per Javadoc (bukan hack) meskipun saya akan menulis ulang metode sebagaieditView.setInputType(InputType.TYPE_NULL);
Bostone
3
ini berfungsi, bagaimanapun, ini menyembunyikan android: hint. Saya menggunakan Android 1.5
Tirtha
ini bagus untuk ketika Anda perlu menutup keyboard dari dialog, tidak perlu mendapatkan instance atau apa pun dan dapat menetapkan ini untuk semua teks edit ketika pengguna menekan tombol yang menutup dialog
I'm_With_Stupid
Berhasil, tetapi juga menyembunyikan kursor. Saya membutuhkan kursor, tetapi tidak ada keyboard sistem.
Stefan Brendle
129

Pembaruan: Saya tidak tahu mengapa solusi ini tidak berfungsi lagi (saya baru saja menguji pada Android 23). Silakan gunakan solusi Saurabh Pareek sebagai gantinya. Ini dia:

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

Jawaban lama:

//Show soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Nguyen Minh Binh
sumber
8
Di mana saya harus meletakkan kode ini? Saya sudah mencoba menempelkan getWindow (). SetSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); di onCreate () tetapi keyboard tidak pernah disembunyikan
user2236096
tidak bekerja, diuji di radioGroup.setOnCheckedChangeListener, API 23
Christian Schäfer
Jika Anda melihat lebih dekat, InputMethodManager.HIDE_IMPLICIT_ONLY dan InputMethodManager.SHOW_IMPLICIT memiliki nilai yang sama, yaitu "1", jadi tidak ada perbedaan antara panggilan-panggilan ini. => tidak bekerja
Palejandro
jika memanggil imm.toggleSoftInput (InputMethodManager.HIDE_IMPLICIT_ONLY, 0); maka keyboard akan ditampilkan di layar :) Implementasi terbaik adalah: github.com/ravindu1024/android-keyboardlistener Malu di Android SDK
Duna
I don't know why this solution is not work any more- Karena itu Android , semuanya akan dapat berubah, mungkin sebagian dari desain yang buruk ... Kami menulis dengan ceroboh, lalu kami mencoret semua dan menulis ulang semuanya.
King King
89
protected void hideSoftKeyboard(EditText input) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(input.getWindowToken(), 0);    
}
Sreedev R
sumber
5
Ini berhasil untuk saya! Tapi mengapa Anda memasukkan input.setInputType (0) ? Saya tidak bisa berinteraksi dengan EditTextView ketika saya memiliki baris kode itu (Ini berhasil ketika saya menghapusnya).
ymerdrengene
Mungkin input.getContext().getSystemService(Context.INPUT_METHOD_SERVICE).
CoolMind
Saya dihapus input.setInputType(0);dari kode ini. Itu mengubah perilaku keyboard dan inputTypeuntuk EditText.
CoolMind
74

Jika semua jawaban lain di sini tidak bekerja untuk Anda seperti yang Anda inginkan, ada cara lain untuk mengontrol keyboard secara manual.

Buat fungsi dengan yang akan mengelola beberapa EditTextproperti:

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

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

Kemudian, pastikan bahwa pada Fokus EditTextAnda membuka / menutup keyboard:

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

Sekarang, kapan pun Anda ingin membuka keyboard, panggil secara manual:

setEditTextFocus(true);

Dan untuk panggilan penutupan:

setEditTextFocus(false);
Rotemmiz
sumber
+1 - Jika Anda ingin memulai aktivitas dengan keyboard tertutup gunakan solusi ini dan tambahkan onclicklistener yang menetapkan setEditTextFocus (true). Bekerja seperti mempesona!
schlingel
Saya mendapatkan 'Tidak dapat menyelesaikan konteks simbol', pada baris kode kedua dan ke-7 dan ke-10.
gimmegimme
Gunakan getContext () sebagai gantinya
Rotemmiz
61

Saurabh Pareek memiliki jawaban terbaik sejauh ini.

Mungkin juga menggunakan bendera yang benar.

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

Contoh penggunaan nyata

/* 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 ... */
}
Alex
sumber
1
Ini adalah yang paling efisien untuk versi terbaru. Anda harus selalu men-tweak untuk versi yang lebih lama. Terutama sebelum v3.
Alex
2
@Mazen: usefragment.getActivity().getSystemService();
Johan S
Ini adalah jawaban paling komprehensif, yang mencakup acara dan sembunyikan.
André Staltz
4
Tidak. Di Samsung Tab saya, Android 5.0, kode yang disebut "sembunyikan keyboard" di atas akan TOGGLE keyboard lunak - jika sudah tersembunyi, akan ditampilkan. Ada alasan fungsi ini memiliki TOGGLE dalam namanya.
ToolmakerSteve
57

dari pencarian, di sini saya menemukan jawaban yang cocok untuk saya

// 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);
shontauro
sumber
Satu-satunya yang bekerja untuk saya untuk Motorola dengan Android 5.1
GMX
55

Jawaban singkatnya

Dalam Anda OnClickpendengar memanggil onEditorActiondari EditTextdenganIME_ACTION_DONE

button.setOnClickListener(new OnClickListener() {

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

Drill-down

Saya merasa metode ini lebih baik, lebih sederhana dan lebih selaras dengan pola desain Android. Dalam contoh sederhana di atas (dan biasanya dalam sebagian besar kasus umum) Anda akan memiliki EditTextfokus yang memiliki / dan juga biasanya adalah orang yang memohon keyboard di tempat pertama (itu pasti dapat memanggilnya dalam banyak skenario umum). Dengan cara yang sama, itu harus menjadi orang yang melepaskan keyboard, biasanya yang dapat dilakukan oleh ImeAction. Lihat saja bagaimana EditTextdengan android:imeOptions="actionDone"berperilaku, Anda ingin mencapai perilaku yang sama dengan cara yang sama.


Periksa jawaban terkait ini

Alex.F
sumber
Inilah jawabannya. Hanya metode yang berfungsi versi lintas. Saya kembali ke pertanyaan ini untuk mengirim jawaban ini karena saya tidak berpikir orang lain tahu
Noah Passalacqua
Ini seharusnya jawaban yang benar. Alih-alih menipu Android untuk menyembunyikan keyboard ketika itu benar-benar harus ada di sana, kami mengatakannya bahwa pengguna selesai, yang pada gilirannya memicu ImeAction [nama bodoh, saya akui] yang sama seolah-olah pengguna telah mengklik "DILAKUKAN" pada keyboard. . Dengan cara ini tidak ada bedanya jika pengguna mengonfirmasi input pada keyboard atau mengetuk tombol UI.
Oliver Hausler
46

Ini seharusnya bekerja:

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);
slinden77
sumber
Berfungsi sebagian, meskipun keyboard disembunyikan "isActive ()" mengembalikan false!
xpto
Tentu saja, memang seharusnya begitu. Atau mungkin saya tidak mengerti Anda. Bagaimanapun, Anda dapat melengkapi kelas dengan hide()dan show()metode untuk memiliki lebih banyak kontrol atas kapan harus ditampilkan dan kapan tidak. Bekerja untuk saya, saya juga melakukannya :) Saya akan mengedit contoh
slinden77
@YoushaAleayoub ya akan. KeyBoard.toggle(fragment.getActivity())
slinden77
@ slinden77, lol, saya sedang berbicara tentang Jawaban Anda ... bukan yang ini Anda komentari. Jadi jawaban itu masih TIDAK berfungsi.
Yousha Aleayoub
@YoushaAleayoub uhm ya itu akan. Pertanyaan aslinya tidak menyebutkan fragmen, kaulah yang menyebutkan fragmen. Jadi jawaban saya benar-benar valid. Untuk menggunakannya dengan fragmen, panggil metode berbeda dari Fragment, seperti berkomentar. Pelajari cara menggunakan metode tolong dan kemudian kembali. Anda membingungkan orang-orang dengan balasan konyol Anda
slinden77
43

Saya menggunakan keyboard khusus untuk memasukkan nomor Hex sehingga saya tidak dapat menampilkan keyboard IMM ...

Di v3.2.4_r1 setSoftInputShownOnFocus(boolean show)ditambahkan untuk mengontrol cuaca atau tidak untuk menampilkan keyboard ketika TextView mendapatkan fokus, tetapi masih tersembunyi sehingga refleksi harus digunakan:

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

Untuk versi yang lebih lama, saya mendapat hasil yang sangat baik (tetapi jauh dari sempurna) dengan OnGlobalLayoutListener, ditambah dengan bantuan dari ViewTreeObserverdari tampilan root saya dan kemudian memeriksa apakah keyboard ditampilkan seperti ini:

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

Solusi terakhir ini dapat menampilkan keyboard untuk sepersekian detik dan mengacaukan pegangan pemilihan.

Ketika di keyboard memasuki layar penuh, onGlobalLayout tidak dipanggil. Untuk menghindarinya, gunakan TextView # setImeOptions (int) atau dalam deklarasi TextView XML:

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

Pembaruan: Baru saja menemukan dialog yang digunakan untuk tidak pernah menampilkan keyboard dan berfungsi di semua versi:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
sergio91pt
sumber
Terima kasih. Dua flag FLAG_ALT_FOCUSABLE_IM dan FLAG_ALT_FOCUSABLE_IM sebenarnya adalah satu-satunya hal yang membantu dalam kasus saya. Saya tidak ingin keyboard ditampilkan di aktivitas saya - bahkan ketika pengguna mengklik edittext. (Saya membuat "keypad" saya sendiri).
Daniel Novak
Solusi keren, namun, jika aktivitas depan Anda bukan layar penuh, keyboard terlihat di belakangnya. Juga bantuan gerakan kursor keyboard juga masih terlihat. Dan itu tidak skinnable.
halxinate
Saya yang kedua itu. Dari semua cara yang mungkin hanya metode getWindow (). SetFlags () bekerja, setidaknya pada stok Android 5.1. Perhatikan bahwa setSoftInputShownOnFocus () sekarang setShowSoftInputOnFocus () dan tidak lagi disembunyikan tetapi tidak berfungsi, setidaknya tidak ketika pengguna menyentuh bidang.
olefevre
"Pembaruan" Anda adalah satu-satunya solusi yang berfungsi untuk saya. Saya mencari solusi setidaknya dua jam :)
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);
    }
}
shobhan
sumber
30

Saya telah menghabiskan lebih dari dua hari mengerjakan semua solusi yang diposting di utas dan menemukan mereka kurang dalam satu atau lain cara. Persyaratan persis saya adalah memiliki tombol yang akan menampilkan keandalan 100% atau menyembunyikan keyboard layar. Ketika keyboard dalam keadaan tersembunyi tidak seharusnya muncul kembali, apa pun bidang input yang diklik pengguna. Saat berada dalam kondisi terlihat, keyboard tidak boleh hilang apa pun tombol yang diklik pengguna. Ini perlu bekerja di Android 2.2+ hingga perangkat terbaru.

Anda dapat melihat implementasi ini berfungsi di RPN bersih aplikasi saya .

Setelah menguji banyak jawaban yang disarankan pada sejumlah ponsel yang berbeda (termasuk perangkat froyo dan gingerbread), menjadi jelas bahwa aplikasi android dapat diandalkan:

  1. Sembunyikan sementara keyboard. Ini akan muncul kembali ketika pengguna memfokuskan bidang teks baru.
  2. Perlihatkan keyboard saat aktivitas dimulai dan atur tanda pada aktivitas yang mengindikasikan bahwa keyboard mereka harus selalu terlihat. Bendera ini hanya dapat disetel saat suatu aktivitas diinisialisasi.
  3. Tandai suatu aktivitas untuk tidak pernah memperlihatkan atau mengizinkan penggunaan keyboard. Bendera ini hanya dapat disetel saat suatu aktivitas diinisialisasi.

Bagi saya, menyembunyikan sementara keyboard tidak cukup. Pada beberapa perangkat ini akan muncul kembali segera setelah bidang teks baru difokuskan. Karena aplikasi saya menggunakan beberapa bidang teks pada satu halaman, memfokuskan bidang teks baru akan menyebabkan keyboard yang tersembunyi muncul kembali.

Sayangnya item 2 dan 3 dalam daftar hanya dapat diandalkan ketika suatu aktivitas sedang dimulai. Setelah aktivitas terlihat, Anda tidak dapat menyembunyikan atau menampilkan keyboard secara permanen. Caranya adalah dengan benar-benar memulai kembali aktivitas Anda ketika pengguna menekan tombol sakelar keyboard. Dalam aplikasi saya ketika pengguna menekan tombol toggle keyboard, kode berikut berjalan:

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

Hal ini menyebabkan aktivitas saat ini disimpan dalam Bundle, dan kemudian aktivitas dimulai, melewati boolean yang menunjukkan apakah keyboard harus ditampilkan atau disembunyikan.

Di dalam metode onCreate kode berikut dijalankan:

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

Jika keyboard lunak ditampilkan, maka InputMethodManager diperintahkan untuk menampilkan keyboard dan jendela diperintahkan untuk membuat input lunak selalu terlihat. Jika keyboard lunak harus disembunyikan maka WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM diatur.

Pendekatan ini bekerja dengan andal pada semua perangkat yang telah saya uji - dari ponsel HTC 4 tahun yang menjalankan Android 2.2 hingga nexus 7 yang menjalankan 4.2.2. Satu-satunya kelemahan dengan pendekatan ini adalah Anda harus berhati-hati dalam menangani tombol kembali. Karena aplikasi saya pada dasarnya hanya memiliki satu layar (dengan kalkulator), saya dapat menimpa onBackPressed () dan kembali ke layar beranda perangkat.

Luke Sleeman
sumber
1
solusi rumit, tapi saya pikir itu terlalu banyak, untuk membuat ulang ribuan objek hanya untuk menyembunyikan Keyboard. Saya tidak tahu siapa yang merancang IMM untuk android, tetapi baunya seperti Windows APi. Menurut pendapat saya, IME yang baik harus memiliki dua metode: sembunyikan dan tunjukkan :-)
rupps
Semua itu benar, tetapi solusi saya memang memiliki satu keuntungan - selalu berhasil! Tidak ada solusi lain yang dapat saya temukan yang akan selalu mengaktifkan keyboard, terlepas dari bidang apa di UI yang menjadi fokus, apa yang telah dilakukan pengguna untuk beralih dan keyboard dan versi android apa yang mereka jalankan: - \
Luke Sleeman
Sobat, aku benar-benar nekat menyembunyikan keyboard. Sudah mencoba ribuan hal dan tidak ada yang berhasil. Tetapi solusi Anda terlalu banyak untuk saya, saya harus membuat ulang seperti 10 fragmen, menginisialisasi layanan, menghapus banyak Referensi Weak .... Anda tahu? GC hanya akan membuang seperti 25mb: S ... Masih mencari cara yang dapat diandalkan untuk melakukannya :(
rupps
@Lakukan dengan baik itu bukan halo dunia ... ini adalah aplikasi yang kompleks untuk tablet. Saya menolak untuk benar-benar menurunkannya dari memori hanya untuk menyembunyikan keyboard konyol ... Pokoknya saya menemukan sesuatu yang berfungsi menggabungkan ribuan solusi yang diusulkan di sini :)
rupps
27

Sebagai alternatif untuk solusi all around ini , jika Anda ingin menutup soft keyboard dari mana saja tanpa memiliki referensi ke bidang (EditText) yang digunakan untuk membuka keyboard, tetapi tetap ingin melakukannya jika bidang itu difokuskan, Anda dapat menggunakan ini (dari Aktivitas):

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

Berkat jawaban SO ini , saya memperoleh yang berikut, yang dalam kasus saya, berfungsi dengan baik ketika menelusuri fragmen 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);
    }
}
ban-geoengineering
sumber
21

Jawaban di atas berfungsi untuk skenario yang berbeda, tetapi Jika Anda ingin menyembunyikan keyboard di dalam tampilan dan berjuang untuk mendapatkan konteks yang tepat coba ini:

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

dan untuk mendapatkan konteksnya, ambil dari konstruktor :)

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

Jika Anda ingin menutup keyboard lunak selama tes unit atau fungsional, Anda dapat melakukannya dengan mengeklik "tombol kembali" dari pengujian Anda:

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

Saya memasukkan "tombol kembali" ke dalam tanda kutip, karena hal di atas tidak memicu onBackPressed()untuk Aktivitas yang dimaksud. Itu hanya menutup keyboard.

Pastikan untuk berhenti sebentar sebelum melanjutkan, karena perlu sedikit waktu untuk menutup tombol kembali, jadi klik berikutnya untuk Tampilan, dll., Tidak akan terdaftar sampai setelah jeda singkat (1 detik cukup lama untuk ).

Peter Ajtai
sumber
16

Inilah cara Anda melakukannya di Mono untuk Android (AKA MonoDroid)

InputMethodManager imm = GetSystemService (Context.InputMethodService) as InputMethodManager;
if (imm != null)
    imm.HideSoftInputFromWindow (searchbox.WindowToken , 0);
Ian Vink
sumber
1
Apa yang ada searchboxdi cuplikan?
PCoder
16

Ini bekerja untuk saya untuk semua perilaku keyboard yang aneh

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);
    }
}
Pinhassi
sumber
1
Rasanya saya sudah mencoba 10 jawaban sebelum ini. Sudah menyerah harapan. Terima kasih sobat.
Bolling
Apa itu mRootView?
justdan0227
14

Tambahkan ke aktivitas Anda android:windowSoftInputMode="stateHidden"di file Manifest. Contoh:

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

Sederhana dan Mudah digunakan, panggil saja hideKeyboardFrom (YourActivity.this); untuk menyembunyikan 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);
}
Naveed Ahmad
sumber
13

Cukup gunakan kode yang dioptimalkan ini dalam aktivitas Anda:

if (this.getCurrentFocus() != null) {
    InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
Hamid FzM
sumber
Bekerja dengan baik. Terima kasih
Alif
12
public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

setelah panggilan di onTouchListener:

findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Utils.hideSoftKeyboard(activity);
        return false;
    }
});
Sagar Maiyad
sumber
Coba ini juga - ini bekerja untuk saya: InputMethodManager imm = ((InputMethodManager) getSystemService (Activity.INPUT_METHOD_SERVICE)); imm.hideSoftInputFromWindow (getWindow (). getCurrentFocus (). getWindowToken (), 0);
zmicer
12

Gunakan ini

this.getWindow().setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Atish Agrawal
sumber
12

Untuk kasus saya, saya menggunakan SearchView di actionbar. Setelah pengguna melakukan pencarian, keyboard akan terbuka lagi.

Menggunakan InputMethodManager tidak menutup keyboard. Saya harus mengosongkan fokus dan menetapkan fokus pada tampilan pencarian ke false:

mSearchView.clearFocus();
mSearchView.setFocusable(false);
tommy chheng
sumber
1
Sangat pintar. Jika pengguna menginginkan pencarian lain, klik saja pencarian lagi.
Alex
SearchView tidak memiliki clearFocus()di halaman API Android, jadi ini tidak bekerja untuk saya, tetapi solusi lain melakukannya (lihat jawaban saya di bawah).
Azurespot
@Noni A, stackoverflow.com/questions/7409288/...
Yousha Aleayoub
12

Saya punya kasing, di mana saya EditTextdapat ditemukan juga dalam AlertDialog, jadi keyboard harus ditutup pada pemberhentian. Kode berikut tampaknya berfungsi di mana saja:

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 );
}
injecteer
sumber
1
Solusi ini lebih baik karena Anda tidak harus mengontrol EditText yang lulus sebagai parameter ke metode hideSoftInputFromWindow (). Ini sangat bagus !!
Billyjoker
12

Saya hampir mencoba semua jawaban ini, saya punya beberapa masalah acak terutama dengan samsung galaxy s5.

Yang akhirnya saya lakukan adalah memaksa acara dan sembunyikan, dan itu bekerja dengan sempurna:

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