Saat fokus input masuk atau keluar dari kolom teks yang dapat diedit, Android akan menampilkan atau menyembunyikan input —seperti keyboard virtual—sebagaimana sesuai. Sistem juga akan menentukan tampilan UI dan kolom teks di atas metode input. Misalnya, saat ruang vertikal di layar dibatasi, kolom teks mungkin mengisi semua ruang di atas metode input.
Di sebagian besar aplikasi, perilaku default inilah yang diperlukan. Namun, dalam beberapa kasus, Anda mungkin menginginkan kontrol lebih besar atas visibilitas metode input dan pengaruhnya terhadap tata letak. Tutorial ini menjelaskan cara mengontrol dan merespons visibilitas metode input.
Tampilkan keyboard virtual saat aktivitas dimulai
Meskipun Android memberikan fokus ke kolom teks pertama dalam tata letak Anda saat aktivitas dimulai, Android tidak akan menampilkan keyboard virtual. Perilaku ini sesuai karena memasukkan teks mungkin bukan tugas utama dalam aktivitas. Namun, jika memasukkan teks merupakan tugas utama, seperti di layar login, Anda mungkin ingin keyboard virtual muncul secara default.
Untuk menampilkan metode input saat aktivitas dimulai, tambahkan
atribut android:windowSoftInputMode
ke
elemen <activity>
dengan nilai "stateVisible"
. Contoh:
<application ... >
<activity
android:windowSoftInputMode="stateVisible" ... >
...
</activity>
...
</application>
Menentukan cara UI Anda merespons
Saat muncul di layar, keyboard virtual akan mengurangi jumlah ruang yang tersedia untuk UI aplikasi Anda. Sistem memutuskan cara menyesuaikan bagian yang terlihat di UI Anda, tetapi mungkin tidak berfungsi dengan benar. Guna memastikan perilaku terbaik bagi aplikasi, tentukan cara sistem menampilkan UI di sisa ruang yang Anda inginkan.
Untuk mendeklarasikan perlakuan pilihan Anda dalam aktivitas, gunakan
atribut android:windowSoftInputMode
dalam elemen <activity>
manifes
dengan salah satu nilai "sesuaikan".
Misalnya, untuk memastikan bahwa sistem mengubah ukuran tata letak Anda ke ruang
yang tersedia—yang membuat semua konten tata letak Anda tetap dapat diakses, meskipun
memerlukan scroll—gunakan "adjustResize"
:
<application ... >
<activity
android:windowSoftInputMode="adjustResize" ... >
...
</activity>
...
</application>
Anda dapat menggabungkan spesifikasi penyesuaian dengan spesifikasi visibilitas keyboard virtual awal dari bagian sebelumnya:
<activity
android:windowSoftInputMode="stateVisible|adjustResize" ... >
...
</activity>
Penentuan "adjustResize"
penting jika UI Anda menyertakan kontrol yang
mungkin perlu segera diakses pengguna setelah atau saat melakukan input teks. Misalnya, jika Anda menggunakan tata letak relatif untuk menempatkan panel tombol di bagian bawah
layar, penggunaan "adjustResize"
akan mengubah ukuran tata letak sehingga panel tombol muncul
di atas keyboard virtual.
Menampilkan keyboard virtual sesuai permintaan
Jika ada metode dalam siklus proses aktivitas di mana Anda ingin memastikan
metode input terlihat, Anda dapat menggunakan
InputMethodManager
untuk menampilkannya.
Misalnya, metode berikut mengambil
View
tempat pengguna diharapkan
mengetik sesuatu, memanggil
requestFocus()
untuk memberikan
fokus, lalu memanggil showSoftInput()
untuk membuka metode input:
Kotlin
fun showSoftKeyboard(view: View) { if (view.requestFocus()) { val imm = getSystemService(InputMethodManager::class.java) imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT) } }
Java
public void showSoftKeyboard(View view) { if (view.requestFocus()) { InputMethodManager imm = getSystemService(InputMethodManager.class); imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); } }
Menampilkan keyboard virtual dengan andal
Ada situasi tertentu, misalnya saat suatu aktivitas dimulai, ketika
menggunakan InputMethodManager.showSoftInput()
untuk menampilkan keyboard virtual
dapat menyebabkan keyboard virtual tidak terlihat oleh pengguna.
Visibilitas keyboard virtual saat menggunakan showSoftInput()
bergantung pada
kondisi berikut:
Tampilan tersebut harus sudah terhubung ke keyboard virtual. (Hal ini pada akhirnya mengharuskan jendela untuk difokuskan dan tampilan editor untuk meminta fokus tampilan dengan
View.requestFocus()
).Visibilitas juga dapat dipengaruhi oleh atribut dan tanda
android:windowSoftInputMode
yang digunakan olehshowSoftInput()
.
Dalam kasus penggunaan tertentu, seperti saat suatu aktivitas dimulai, beberapa
kondisi wajib ini tidak terpenuhi. Sistem tidak menganggap tampilan
terhubung ke keyboard virtual, mengabaikan panggilan showSoftInput()
,
dan keyboard virtual tidak terlihat oleh pengguna.
Untuk memastikan keyboard virtual ditampilkan dengan akurat, Anda dapat menggunakan alternatif berikut:
- (Direkomendasikan) Gunakan
WindowInsetsControllerCompat
. Objek ini menampilkan keyboard virtual selamaActivity.onCreate()
seperti yang ditunjukkan dalam cuplikan kode berikut. Panggilan dijamin akan dijadwalkan setelah jendela difokus.
Kotlin
editText.requestFocus() WindowCompat.getInsetsController(window, editText)!!.show(WindowInsetsCompat.Type.ime())
Java
editText.requestFocus(); WindowCompat.getInsetsController(getWindow(), editText).show(WindowInsetsCompat.Type.ime());
- Posting file yang dapat dijalankan. Hal ini memastikan aplikasi Anda menunggu hingga menerima
peristiwa fokus jendela dari
View.onWindowFocusChanged()
sebelum memanggilshowSoftInput()
.
Kotlin
class MyEditText : EditText() { ... override fun onWindowFocusChanged(hasWindowFocus: Boolean) { if (hasWindowFocus) { requestFocus() post { val imm: InputMethodManager = getSystemService(InputMethodManager::class.java) imm.showSoftInput(this, 0) } } } }
Java
public class MyEditText extends EditText { ... @Override public void onWindowFocusChanged(boolean hasWindowFocus) { if (hasWindowFocus) { requestFocus(); post(() -> { InputMethodManager imm = getSystemService(InputMethodManager.class); imm.showSoftInput(this, 0); }); } } }
Tangani tanda visibilitas runtime dengan cermat
Saat mengalihkan visibilitas keyboard virtual saat runtime, berhati-hatilah agar tidak meneruskan nilai
flag tertentu ke dalam metode ini. Misalnya, jika aplikasi mengharapkan
keyboard virtual muncul saat memanggil
View.getWindowInsetsController().show(ime())
dalam Activity.onCreate()
selama
aktivitas dimulai, developer aplikasi harus berhati-hati untuk tidak menetapkan tanda
SOFT_INPUT_STATE_HIDDEN
atau SOFT_INPUT_STATE_ALWAYS_HIDDEN
selama peluncuran awal jika keyboard virtual tersembunyi secara tidak terduga.
Sistem biasanya menyembunyikan keyboard virtual secara otomatis
Pada kebanyakan situasi, sistem menangani penyembunyian keyboard virtual. Hal ini dapat berupa salah satu kasus berikut:
- Pengguna menyelesaikan tugas di kolom teks.
- Pengguna menekan tombol kembali atau gestur geser dengan navigasi kembali.
- Pengguna membuka aplikasi lain, dan aplikasi lain tersebut telah menetapkan tanda
SOFT_INPUT_STATE_HIDDEN
atauSOFT_INPUT_STATE_ALWAYS_HIDDEN
saat tampilan mendapatkan fokus.
Menyembunyikan keyboard virtual secara manual berdasarkan perilaku sistem sebelumnya
Aplikasi Anda harus menyembunyikan keyboard virtual secara manual dalam beberapa situasi—misalnya, saat kolom teks kehilangan fokus di
View.OnFocusChangeListener.onFocusChange
. Gunakan teknik ini dengan bijak; menutup keyboard virtual secara tiba-tiba akan mengganggu pengalaman pengguna.
Jika aplikasi menyembunyikan keyboard virtual secara manual, Anda perlu tahu apakah keyboard virtual ditampilkan secara eksplisit atau implisit:
Keyboard virtual dianggap telah secara eksplisit ditampilkan setelah panggilan ke
showSoftInput()
.Sebaliknya, keyboard virtual dianggap telah ditampilkan secara implisit dalam salah satu kondisi berikut:
- Sistem menampilkan keyboard virtual saat menerapkan
android:windowSoftInputMode
. - Aplikasi Anda meneruskan
SHOW_IMPLICIT
keshowSoftInput()
.
- Sistem menampilkan keyboard virtual saat menerapkan
Biasanya, hideSoftInputFromWindow()
menyembunyikan keyboard virtual terlepas dari
cara permintaannya, tetapi dengan HIDE_IMPLICIT_ONLY
, opsi ini dapat dibatasi untuk hanya menutup keyboard virtual yang diminta secara implisit.
Menampilkan tampilan dialog atau overlay di atas keyboard virtual
Dalam beberapa situasi, aktivitas editor mungkin perlu membuat dialog atau jendela overlay yang tidak dapat diedit di atas keyboard virtual.
Aplikasi Anda memiliki beberapa opsi, yang dijelaskan di bagian berikut.
Singkatnya, pastikan untuk menangani flag jendela dari keyboard virtual yang menargetkan jendela dengan benar sehingga memenuhi ekspektasi berikut terkait pengurutan vertikal (lapisan z):
- Tidak ada flag (kasus normal): Di belakang lapisan keyboard virtual, dan dapat menerima teks.
FLAG_NOT_FOCUSABLE
: Di atas lapisan keyboard virtual, tetapi tidak dapat menerima teks.FLAG_ALT_FOCUSABLE_IM
: Di atas lapisan keyboard virtual, dapat difokuskan, tetapi tidak terhubung ke keyboard virtual. Juga memblokir semua tampilan di bawahnya agar tidak terhubung ke keyboard virtual. Hal ini berguna untuk menampilkan dialog aplikasi yang tidak menggunakan input teks di atas lapisan keyboard virtual.FLAG_NOT_FOCUSABLE
danFLAG_ALT_FOCUSABLE_IM
: Di belakang lapisan keyboard virtual, tetapi tidak dapat menerima teks.FLAG_NOT_FOCUSABLE
danFLAG_NOT_TOUCH_MODAL
: Di atas keyboard virtual, dan memungkinkan peristiwa sentuh "melalui" jendela ke keyboard virtual.
Membuat dialog
Gunakan flag jendela dialog
FLAG_ALT_FOCUSABLE_IM
untuk menjaga dialog tetap berada di atas keyboard virtual, dan untuk
mencegah keyboard virtual mendapatkan fokus:
Kotlin
val content = TextView(this) content.text = "Non-editable dialog on top of soft keyboard" content.gravity = Gravity.CENTER val builder = AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content) mDialog = builder.create() mDialog!!.window!! .addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) mDialog!!.show()
Java
TextView content = new TextView(this); content.setText("Non-editable dialog on top of soft keyboard"); content.setGravity(Gravity.CENTER); final AlertDialog.Builder builder = new AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content); mDialog = builder.create(); mDialog.getWindow().addFlags(FLAG_ALT_FOCUSABLE_IM); mDialog.show();
Membuat tampilan overlay
Buat tampilan overlay yang menentukan jenis jendela TYPE_APPLICATION_OVERLAY
dan flag jendela FLAG_ALT_FOCUSABLE_IM
oleh aktivitas yang ditargetkan keyboard virtual.
Kotlin
val params = WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ WindowManager.LayoutParams.TYPE_APPLICATION, /* Overlay window type */ WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */ or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, /* Allow touch event send to soft keyboard behind the overlay */ PixelFormat.TRANSLUCENT ) params.title = "Overlay window" mOverlayView!!.layoutParams = params windowManager.addView(mOverlayView, params)
Java
WindowManager.LayoutParams params = new WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ TYPE_APPLICATION, /* Overlay window type */ FLAG_ALT_FOCUSABLE_IM /* No need to allow for text input on top of the soft keyboard */ | FLAG_NOT_TOUCH_MODAL, /* Allow touch event send to soft keyboard behind the overlay */ PixelFormat.TRANSLUCENT); params.setTitle("Overlay window"); mOverlayView.setLayoutParams(params); getWindowManager().addView(mOverlayView, params);
Menampilkan dialog atau tampilan di bawah keyboard virtual
Aplikasi Anda mungkin perlu membuat dialog atau jendela yang memiliki properti berikut:
- Muncul di bawah keyboard virtual yang diminta oleh aktivitas editor sehingga tidak terpengaruh oleh input teks.
- Tetap memperhatikan perubahan pada perubahan ukuran inset keyboard virtual untuk menyesuaikan dialog atau tata letak jendela.
Dalam hal ini, aplikasi Anda memiliki beberapa opsi. Bagian berikut menjelaskan opsi tersebut.
Membuat dialog
Buat dialog dengan menetapkan flag jendela FLAG_NOT_FOCUSABLE
dan flag jendela
FLAG_ALT_FOCUSABLE_IM
:
Kotlin
val content = TextView(this) content.text = "Non-editable dialog behind soft keyboard" content.gravity = Gravity.CENTER val builder = AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content) mDialog = builder.create() mDialog!!.window!! .addFlags(FLAG_NOT_FOCUSABLE or FLAG_ALT_FOCUSABLE_IM) mDialog!!.show()
Java
TextView content = new TextView(this); content.setText("Non-editable dialog behind soft keyboard"); content.setGravity(Gravity.CENTER); final AlertDialog.Builder builder = new AlertDialog.Builder(this) .setTitle("Soft keyboard layering demo") .setView(content); mDialog = builder.create(); mDialog.getWindow() .addFlags(FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM); mDialog.show();
Membuat tampilan overlay
Buat tampilan overlay dengan menetapkan flag jendela FLAG_NOT_FOCUSABLE
dan flag jendela FLAG_ALT_FOCUSABLE_IM
:
Kotlin
val params = WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ WindowManager.LayoutParams.TYPE_APPLICATION, /* Overlay window type */ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, PixelFormat.TRANSLUCENT ) params.title = "Overlay window" mOverlayView!!.layoutParams = params windowManager.addView(mOverlayView, params)
Java
WindowManager.LayoutParams params = new WindowManager.LayoutParams( width, /* Overlay window width */ height, /* Overlay window height */ TYPE_APPLICATION, /* Overlay window type */ FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM, PixelFormat.TRANSLUCENT); params.setTitle("Overlay window"); mOverlayView.setLayoutParams(params); getWindowManager().addView(mOverlayView, params);