Saya perlu melakukan hal yang sangat sederhana - cari tahu apakah keyboard perangkat lunak ditampilkan. Apakah ini mungkin di Android?
516
Saya perlu melakukan hal yang sangat sederhana - cari tahu apakah keyboard perangkat lunak ditampilkan. Apakah ini mungkin di Android?
Jawaban:
NEW ANSWER ditambahkan 25 Jan 2012
Sejak menulis jawaban di bawah ini, seseorang memberi petunjuk kepada saya tentang keberadaan ViewTreeObserver dan teman-teman, API yang telah mengintai di SDK sejak versi 1.
Daripada memerlukan jenis Tata Letak khusus, solusi yang jauh lebih sederhana adalah memberikan tampilan root aktivitas Anda ID yang dikenal, katakan
@+id/activityRoot
, kaitkan GlobalLayoutListener ke ViewTreeObserver, dan dari sana hitung perbedaan ukuran antara root tampilan aktivitas Anda dan ukuran jendela:Menggunakan utilitas seperti:
Mudah!
Catatan: Aplikasi Anda harus mengatur tanda ini di Android Manifest
android:windowSoftInputMode="adjustResize"
jika tidak, solusi di atas tidak akan berfungsi.JAWABAN ASLI
Ya itu mungkin, tapi itu jauh lebih sulit dari yang seharusnya.
Jika saya perlu peduli kapan keyboard muncul dan menghilang (yang cukup sering) maka apa yang saya lakukan adalah menyesuaikan kelas tata letak tingkat atas saya menjadi yang ditimpa
onMeasure()
. Logika dasar adalah bahwa jika tata letak menemukan dirinya mengisi secara signifikan kurang dari total luas jendela, maka keyboard lunak mungkin ditampilkan.Kemudian di kelas Aktivitas Anda ...
sumber
((ViewGroup) findViewById(android.R.id.content)).getChildAt(0)
android.R.id.content
) Anda akan dapat lebih percaya diri mengatakan bahwaSystem
alih - alih aplikasi Anda adalah entitas yang mengubah tingginya. Akan jauh lebih aman bagi tim Android untuk memberi kami istirahat dan beri tahu kami setidaknya hal-hal dasar tentang input SoftKeyboard.heightDiff
akan selalu mencakup ketinggian bilah tindakan. Di jawaban baru yang telah diabaikan oleh pengujian apakah ketinggian itu lebih besar dari beberapa konstanta, tetapi 100 piksel tidak cukup untuk perangkat xxhdpi seperti Nexus 4. Pertimbangkan untuk mengubah nilai itu ke DP jika Anda benar-benar ingin menggunakan pekerjaan yang peretasan ini- sekitar.Jadi semoga ini membantu seseorang keluar.
Jawaban baru yang diberikan Reuben Scratton sangat bagus dan sangat efisien, tetapi itu benar-benar hanya berfungsi jika Anda mengatur windowSoftInputMode Anda untuk menyesuaikanResize. Jika Anda mengaturnya ke AdjustPan, masih tidak mungkin mendeteksi apakah keyboard terlihat menggunakan potongan kode-nya atau tidak. Untuk mengatasinya, saya membuat modifikasi kecil pada kode di atas.
sumber
TwoDScrollerView
mirip dengan stackoverflow.com/a/5224088/530513 meskipun dengan zooming juga. Anak itu tidak sederhanaImageView
tetapi tata letak kustom (meluasRelativeLayout
) tetapi tidak dapat mendeteksi keyboard menggunakan solusi yang disarankan meskipun pengaturanandroid:windowSoftInputMode="adjustResize"
. Terima kasih!ActionBar
danActionBarSherlock
. Terima kasih banyak! Omong-omong, ada metoder.height()
:)heightDiff > root.getRootView().getHeight() / 4
adalah nilai yang baik untuk bekerja dengan perangkat resolusi tinggi. 100px adalah singkatnya. di Nexus 5 dengan 1080x1920 res, 1920 - (996-75)>? 100 = 999 1920 - (1776-75)>? 100 = 219 // keyboard menyala di galaxy s2 dengan 480x800 res, 800 - (800-38)>? 100 = 38 800 - (410-38)>? 100 = 428 // keyboard naik jadi, angka ajaib 100px tidak cukup baik.Sudah selamanya dalam hal komputer tetapi pertanyaan ini masih sangat relevan!
Jadi saya telah mengambil jawaban di atas dan telah menggabungkan dan memperbaikinya sedikit ...
Bekerja untuk saya :)
CATATAN: Jika Anda melihat bahwa DefaultKeyboardDP tidak sesuai dengan perangkat Anda bermain dengan nilai dan memposting komentar untuk semua orang untuk mengetahui apa yang seharusnya menjadi nilai ... akhirnya kami akan mendapatkan nilai yang benar untuk semua perangkat!
Untuk detail lebih lanjut, lihat implementasi di Cyborg
sumber
Maaf atas jawaban yang terlambat, tetapi saya telah membuat kelas pembantu kecil untuk menangani acara buka / tutup dengan memberi tahu pendengar dan hal-hal bermanfaat lainnya, mungkin seseorang akan merasa terbantu:
Contoh penggunaan:
sumber
getLastKeyboardHeightInPx()
tidak termasuk ketinggian baris itu. Apakah Anda tahu cara untuk memperhitungkannya juga?Beberapa peningkatan untuk menghindari kesalahan mendeteksi visibilitas keyboard lunak pada perangkat kepadatan tinggi:
Ambang batas perbedaan ketinggian harus didefinisikan sebagai 128 dp , bukan 128 piksel .
Lihat dokumen desain Google tentang Metrik dan Kotak , 48 dp adalah ukuran yang nyaman untuk objek sentuh dan 32 dp minimum untuk tombol. Keyboard lunak generik harus menyertakan 4 baris tombol, jadi tinggi minimum keyboard harus: 32 dp * 4 = 128 dp , itu berarti ukuran ambang batas harus ditransfer ke piksel dengan mengalikan kepadatan perangkat. Untuk perangkat xxxhdpi (kepadatan 4), ambang tinggi keyboard lunak harus 128 * 4 = 512 piksel.
Perbedaan tinggi antara tampilan root dan area yang terlihat:
tinggi tampilan root - tinggi status bar - tinggi bingkai terlihat = tampilan dasar root - bawah bingkai terlihat, karena tinggi status bar sama dengan bagian atas bingkai terlihat pandangan root.
sumber
Saya menggunakan sedikit waktu untuk mencari tahu ini ... Saya menjalankannya beberapa CastExceptions, tetapi menemukan bahwa Anda dapat menggantikan Anda LinearLayout di layout.xml dengan nama kelas.
Seperti ini:
Dengan begitu Anda tidak mengalami masalah pemeran.
... dan jika Anda tidak ingin melakukan ini di setiap halaman, saya sarankan Anda menggunakan "MasterPage di Android". Lihat tautan di sini: http://jnastase.alner.net/archive/2011/01/08/ldquomaster-pagesrdquo-in-android.aspx
sumber
Memeriksa ketinggian elemen tidak dapat diandalkan karena beberapa keyboard seperti WifiKeyboard memiliki tinggi nol.
Sebagai gantinya, Anda dapat menggunakan hasil panggil balik showSoftInput () dan hideSoftInput () untuk memeriksa status keyboard. Rincian lengkap dan kode contoh di
https://rogerkeays.com/how-to-check-if-the-software-keyboard-is-shown-in-android
sumber
Idenya adalah, jika Anda perlu menyembunyikan keyboard Anda dan memeriksa status input lunak pada saat yang sama, gunakan solusi berikut:
Metode ini mengembalikan true jika keyboard ditampilkan sebelum bersembunyi.
sumber
Saya menemukan bahwa kombinasi metode @ Reuben_Scratton bersama dengan metode @ Yogesh tampaknya bekerja paling baik. Menggabungkan metode mereka akan menghasilkan sesuatu seperti ini:
sumber
Anda dapat mengamati persembunyian papan tombol dengan menggunakan decorView aktivitas.
sumber
Alih-alih mengasumsikan perbedaan coding saya melakukan sesuatu seperti ini, karena saya tidak punya opsi menu di aplikasi saya.
sumber
Ada juga solusi dengan insets sistem, tetapi hanya bekerja dengan
API >= 21
(Android L
). Katakan sudahBottomNavigationView
, yang merupakan anak dariLinearLayout
dan Anda perlu menyembunyikannya saat keyboard ditampilkan:Yang perlu Anda lakukan adalah memperluas
LinearLayout
sedemikian rupa:Idenya adalah ketika keyboard ditampilkan, insets sistem diubah dengan
.bottom
nilai yang cukup besar .sumber
Ada metode tersembunyi yang bisa membantu untuk ini
InputMethodManager.getInputMethodWindowVisibleHeight
,. Tapi saya tidak tahu mengapa itu disembunyikan.sumber
Tak satu pun dari solusi ini yang akan berfungsi untuk Lollipop seperti apa adanya. Di Lollipop
activityRootView.getRootView().getHeight()
termasuk ketinggian bilah tombol, sedangkan mengukur tampilan tidak. Saya telah mengadaptasi solusi terbaik / paling sederhana di atas untuk bekerja dengan Lollipop.sumber
Saya baru saja menemukan bug saat menggunakan sebagian besar solusi di atas yang menyarankan menambahkan nomor tetap.
S4 memiliki dpi tinggi yang mengakibatkan ketinggian bilah navigasi menjadi 100px sehingga aplikasi saya berpikir bahwa keyboard terbuka sepanjang waktu.
Jadi dengan semua ponsel beresolusi tinggi yang baru dirilis saya percaya menggunakan nilai kode keras bukan ide yang baik untuk jangka panjang.
Pendekatan yang lebih baik yang saya temukan setelah beberapa pengujian pada berbagai layar dan perangkat adalah menggunakan persentase. Dapatkan perbedaan antara decorView dan konten aplikasi Anda dan kemudian periksa berapa persentase perbedaan itu. Dari statistik yang saya dapatkan, sebagian besar nav bar (terlepas dari ukuran, resolusi dll.) Akan mengambil antara 3% hingga 5% dari layar. Di mana seolah-olah keyboard terbuka itu mengambil antara 47% hingga 55% dari layar.
Sebagai kesimpulan solusi saya adalah untuk memeriksa apakah diff lebih dari 10% maka saya menganggap itu keyboard terbuka.
sumber
Saya menggunakan sedikit varian dari jawaban Reuban, yang terbukti lebih membantu dalam keadaan tertentu, terutama dengan perangkat resolusi tinggi.
sumber
R.id.activityRoot
, Anda cukup menggunakanandroid.R.id.content
yang persis Anda butuhkan.Sudah selamanya dalam hal komputer tetapi pertanyaan ini masih sangat relevan! Jadi saya telah mengambil jawaban di atas dan telah menggabungkan dan memperbaikinya sedikit ...
Ini bekerja untuk saya.
sumber
Coba ini:
sumber
Jawaban saya pada dasarnya sama dengan jawaban Kachi, tetapi saya membungkusnya menjadi kelas pembantu yang bagus untuk membersihkan cara penggunaannya di seluruh aplikasi saya.
Anda dapat menggunakan ini untuk mendeteksi perubahan keyboard di mana saja di seluruh aplikasi seperti ini:
Catatan: hanya gunakan salah satu panggilan "daftar". Mereka semua bekerja sama dan hanya ada untuk kenyamanan
sumber
Anda dapat mencoba ini, bekerja sangat baik untuk saya:
sumber
Saya mengalami kesulitan mempertahankan keadaan keyboard saat mengubah orientasi fragmen dalam viewpager. Saya tidak yakin mengapa, tetapi sepertinya tidak stabil dan bertindak berbeda dari Kegiatan standar.
Untuk mempertahankan keadaan keyboard dalam hal ini, pertama Anda harus menambahkan
android:windowSoftInputMode = "stateUnchanged"
keAndroidManifest.xml
. Anda mungkin memperhatikan, bahwa ini tidak benar-benar menyelesaikan seluruh masalah - keyboard tidak terbuka untuk saya jika sebelumnya dibuka sebelum perubahan orientasi. Dalam semua kasus lain, perilaku itu tampaknya benar.Kemudian, kita perlu mengimplementasikan salah satu solusi yang disebutkan di sini. Yang terbersih yang saya temukan adalah milik George Maisuradze - gunakan panggilan balik boolean dari hideSoftInputFromWindow:
Saya menyimpan nilai ini dalam
onSaveInstanceState
metode Fragmen saya dan mengambilnyaonCreate
. Kemudian, saya secara paksa menunjukkan keyboardonCreateView
jika memiliki nilaitrue
(mengembalikan benar jika keyboard terlihat sebelum benar-benar menyembunyikannya sebelum penghancuran Fragmen).sumber
Inilah solusi saya, dan itu berhasil. Alih-alih mencari ukuran piksel cukup periksa bahwa ketinggian tampilan konten telah berubah atau tidak:
sumber
Jangan membuat kode keras. Cara terbaik adalah Anda harus mengubah ukuran tampilan saat di Dapatkan Fokus pada EditText dengan KeyBord Show. Anda dapat melakukan ini menambahkan properti ukuran pada aktivitas ke dalam file Manifest menggunakan kode di bawah ini.
android:windowSoftInputMode="adjustResize"
sumber
Ada metode langsung untuk mengetahuinya. Dan, itu tidak memerlukan perubahan Tata Letak.
Jadi, ia bekerja dalam mode layar penuh imersif juga.
Kuncinya adalah Anda mencoba menyembunyikan atau menampilkan keyboard lunak dan menangkap hasil percobaan itu.
Jangan panik, ini tidak benar-benar menunjukkan atau menyembunyikan keyboard. Kami hanya meminta negara.
Agar tetap terkini, Anda cukup mengulangi operasi, misalnya setiap 200 milidetik, menggunakan Handler.
Anda menemukan implementasi di sini: https://stackoverflow.com/a/27567074/2525452
sumber
Saya pikir metode ini akan membantu Anda untuk mengetahui apakah keybord terlihat atau tidak.
sumber
Jawaban baru Reuben Scratton (menghitung HeightDiff
int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
) tidak akan berfungsi dalam aktivitas jika Anda mengatur mode status bar transparan.jika Anda menggunakan bilah status transparan,
activityRootView.getHeight()
tidak akan pernah mengubah cuaca keyboard lunak terlihat. itu akan selalu mengembalikan ketinggian aktivitas dan status bar.Sebagai contoh, Nexus 4, Android 5.0.1, disetel
android:windowTranslucentStatus
ke true, itu akan mengembalikan 1184 selamanya, bahkan saat sedang opend. Jika Anda mengaturandroid:windowTranslucentStatus
false, itu akan mengembalikan Tinggi dengan benar, jika saya tidak terlihat, itu mengembalikan 1134 (tidak termasuk status bar)。 tutup ime, itu akan mengembalikan 5xx mungkin (tergantung pada tinggi ime)Saya tidak tahu apakah ini bug, saya sudah mencoba 4.4.4 dan 5.0.1, hasilnya sama.
Jadi, hingga sekarang, jawaban kedua yang paling disepakati, solusi Kachi akan menjadi cara paling aman untuk menghitung ketinggian waktu. Ini salinannya:
sumber
Metode yang tidak memerlukan LayoutListener
Dalam kasus saya, saya ingin menyimpan keadaan keyboard sebelum mengganti Fragmen saya. Saya memanggil metode hideSoftInputFromWindow dari
onSaveInstanceState
, yang menutup keyboard dan mengembalikan saya apakah keyboard itu terlihat atau tidak.Metode ini mudah tetapi dapat mengubah kondisi keyboard Anda.
sumber
Saya tahu bahwa ini adalah posting lama tetapi saya pikir ini adalah pendekatan paling sederhana yang saya tahu dan perangkat pengujian saya adalah Nexus 5. Saya belum mencobanya di perangkat lain. Berharap bahwa orang lain akan membagikan pendekatan mereka jika mereka menemukan kode saya tidak baik :)
imm.hideSoftInputFromWindow mengembalikan boolean.
Terima kasih,
sumber
Fungsi di atas adalah apa yang saya gunakan untuk memeriksa apakah Keyboard terlihat. Jika ya, maka saya akan menutupnya.
Di bawah ini menunjukkan dua metode yang diperlukan.
Pertama, tentukan ketinggian Window yang bisa diterapkan di onCreate.
Kemudian, tambahkan metode boolean yang mendapatkan tinggi Window pada saat itu. Jika tidak cocok dengan aslinya (dengan asumsi Anda tidak mengubahnya sepanjang jalan ...) maka, keyboard terbuka
Frotz!
sumber
Saya tahu seberapa tepat Anda dapat menentukan apakah keyboard disembunyikan atau tidak.
Ini berfungsi untuk tablet. Ketika bilah navigasi ditampilkan secara horizontal.
sumber