Membuat metode input

Editor metode input (IME) adalah kontrol pengguna yang memungkinkan pengguna memasukkan teks. Android menyediakan kerangka kerja metode input yang dapat diperluas yang memungkinkan aplikasi menyediakan metode input alternatif kepada pengguna, seperti keyboard virtual atau input ucapan. Setelah menginstal IME, pengguna dapat memilih salah satunya dari setelan sistem dan menggunakannya di seluruh sistem. Hanya satu IME yang dapat diaktifkan dalam satu waktu.

Untuk menambahkan IME ke sistem Android, buat aplikasi Android yang berisi class yang memperluas InputMethodService. Selain itu, Anda biasanya membuat "setelan" yang meneruskan opsi ke layanan IME. Anda juga dapat menentukan UI setelan yang ditampilkan sebagai bagian dari setelan sistem.

Halaman ini membahas topik berikut:

Jika Anda belum pernah bekerja dengan IME, baca artikel pengantar Metode Input di Layar terlebih dahulu.

Siklus proses IME

Diagram berikut menjelaskan siklus proses IME:

Gambar yang menunjukkan siklus proses IME.
Gambar 1. Siklus proses IME.

Bagian berikut menjelaskan cara menerapkan UI dan kode terkait IME yang mengikuti siklus proses ini.

Mendeklarasikan komponen IME dalam manifes

Di sistem Android, IME adalah aplikasi Android yang berisi layanan IME khusus. Tujuan file manifes aplikasi harus mendeklarasikan layanan, meminta izin yang diperlukan, menyediakan filter intent yang cocok dengan tindakan action.view.InputMethod, dan memberikan metadata yang mendefinisikan karakteristik IME. Selain itu, untuk menyediakan antarmuka setelan yang memungkinkan pengguna mengubah perilaku IME, Anda dapat menentukan yang dapat diluncurkan dari Setelan Sistem.

Cuplikan berikut mendeklarasikan layanan IME. Cuplikan ini meminta izin BIND_INPUT_METHOD agar layanan dapat menghubungkan IME ke sistem, menyiapkan filter intent yang cocok dengan tindakan android.view.InputMethod, dan menentukan metadata untuk IME:

<!-- Declares the input method service. -->
<service android:name="FastInputIME"
    android:label="@string/fast_input_label"
    android:permission="android.permission.BIND_INPUT_METHOD">
    <intent-filter>
        <action android:name="android.view.InputMethod" />
    </intent-filter>
    <meta-data android:name="android.view.im"
               android:resource="@xml/method" />
</service>

Cuplikan berikutnya mendeklarasikan aktivitas setelan untuk IME. Fungsi ini memiliki filter intent untuk ACTION_MAIN yang menunjukkan bahwa aktivitas ini adalah titik entri utama untuk aplikasi IME:

<!-- Optional: an activity for controlling the IME settings. -->
<activity android:name="FastInputIMESettings"
    android:label="@string/fast_input_settings">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
    </intent-filter>
</activity>

Anda juga dapat memberikan akses ke setelan IME langsung dari UI-nya.

API metode input

Kelas yang khusus untuk IME ditemukan dalam android.inputmethodservice dan android.view.inputmethod paket. Class KeyEvent penting untuk menangani karakter {i>keyboard<i}.

Bagian tengah IME adalah komponen layanan—class yang memperluas InputMethodService. Selain mengimplementasikan siklus proses layanan normal, memiliki callback untuk menyediakan UI IME, menangani input pengguna, dan mengirimkan teks ke yang memiliki fokus. Secara default, class InputMethodService menyediakan sebagian besar penerapan untuk mengelola status dan visibilitas IME serta berkomunikasi dengan kolom input saat ini.

Class berikut juga penting:

BaseInputConnection
Menentukan saluran komunikasi dari InputMethod kembali ke aplikasi yang menerima inputnya. Anda menggunakannya untuk membaca teks di sekitar kursor, meng-commit teks ke kotak teks, dan mengirim peristiwa tombol mentah ke aplikasi. Aplikasi harus memperluas class ini, bukan mengimplementasikan antarmuka dasar InputConnection.
KeyboardView
Ekstensi View yang merender keyboard dan merespons peristiwa input pengguna. Tata letak keyboard ditentukan oleh instance Keyboard, yang dapat Anda tentukan dalam file XML.

Mendesain UI metode input

Ada dua elemen visual utama untuk IME: tampilan input dan kandidat. Anda hanya perlu menerapkan elemen yang relevan dengan metode input yang sedang Anda desain.

Tampilan input

Tampilan input adalah UI tempat pengguna memasukkan teks dalam bentuk klik tombol, tulisan tangan, atau gestur. Ketika IME ditampilkan untuk pertama kalinya, sistem akan memanggil onCreateInputView() . Dalam penerapan metode ini, buat tata letak yang ingin ditampilkan di jendela IME dan kembalikan tata letak ke sistem. Cuplikan berikut menunjukkan contoh penerapan metode onCreateInputView():

Kotlin

override fun onCreateInputView(): View {
    return layoutInflater.inflate(R.layout.input, null).apply {
        if (this is MyKeyboardView) {
            setOnKeyboardActionListener(this@MyInputMethod)
            keyboard = latinKeyboard
        }
    }
}

Java

@Override
public View onCreateInputView() {
    MyKeyboardView inputView =
        (MyKeyboardView) getLayoutInflater().inflate(R.layout.input, null);

    inputView.setOnKeyboardActionListener(this);
    inputView.setKeyboard(latinKeyboard);

    return inputView;
}

Dalam contoh ini, MyKeyboardView adalah instance implementasi kustom dari KeyboardView yang merender Keyboard.

Tampilan kandidat

Tampilan kandidat adalah UI tempat IME menampilkan saran atau koreksi kata yang mungkin untuk dipilih pengguna. Dalam siklus proses IME, sistem akan memanggil onCreateCandidatesView() jika sudah siap untuk menampilkan tampilan kandidat. Dalam penerapan metode ini, kembalikan tata letak yang menampilkan saran kata, atau kembalikan null jika Anda tidak ingin menampilkan apa pun. Respons null adalah perilaku default, sehingga Anda tidak perlu menerapkannya jika tidak memberikan saran.

Pertimbangan desain UI

Bagian ini menjelaskan beberapa pertimbangan desain UI untuk IME.

Menangani beberapa ukuran layar

UI untuk IME Anda harus dapat diskalakan untuk berbagai ukuran layar dan menangani lanskap serta orientasi potret. Dalam mode IME non-layar penuh, berikan ruang yang cukup agar aplikasi dapat menampilkan kolom teks dan konteks terkait, sehingga IME tidak menempati lebih dari setengah layar. Dalam mode IME layar penuh, hal ini bukan masalah.

Menangani jenis input berbeda

Kolom teks Android memungkinkan Anda menetapkan jenis input tertentu, seperti teks bentuk bebas, angka, URL, alamat email, dan {i>string<i} pencarian. Saat mengimplementasikan IME baru, deteksi jenis input dari setiap IME dan menyediakan antarmuka yang sesuai. Namun, Anda tidak perlu menyiapkan IME untuk memeriksa apakah pengguna memasukkan teks yang valid untuk jenis input. Hal ini merupakan tanggung jawab aplikasi yang memiliki kolom teks.

Misalnya, berikut ini adalah antarmuka yang disediakan IME Latin untuk teks platform Android masukan:

Gambar yang menampilkan input teks di IME Latin
Gambar 2. Input teks IME Latin.

Dan inilah antarmuka yang disediakan IME Latin untuk platform Android input numerik:

Gambar yang menampilkan input numerik pada IME Latin
Gambar 3. Input numerik IME Latin.

Saat kolom input menerima fokus dan IME Anda dimulai, sistem akan memanggil onStartInputView(), meneruskan objek EditorInfo yang berisi detail tentang jenis input dan atribut lain dari kolom teks. Pada objek ini, tindakan inputType berisi jenis input kolom teks.

Kolom inputType adalah int yang berisi pola bit untuk berbagai setelan jenis input. Untuk mengujinya untuk jenis input kolom teks, samarkan dengan konstanta TYPE_MASK_CLASS, seperti ini:

Kotlin

inputType and InputType.TYPE_MASK_CLASS

Java

inputType & InputType.TYPE_MASK_CLASS

Pola bit jenis input dapat memiliki salah satu dari beberapa nilai, termasuk:

TYPE_CLASS_NUMBER
Kolom teks untuk memasukkan angka. Seperti yang diilustrasikan dalam gambar 3, IME Latin menampilkan tombol angka untuk kolom jenis ini.
TYPE_CLASS_DATETIME
Kolom teks untuk memasukkan tanggal dan waktu.
TYPE_CLASS_PHONE
Kolom teks untuk memasukkan nomor telepon.
TYPE_CLASS_TEXT
Kolom teks untuk memasukkan karakter yang didukung.

Konstanta ini dijelaskan secara lebih detail dalam dokumentasi referensi untuk InputType.

Kolom inputType dapat berisi bit lain yang menunjukkan varian jenis kolom teks, seperti:

TYPE_TEXT_VARIATION_PASSWORD
Varian TYPE_CLASS_TEXT untuk memasukkan sandi. Metode input menampilkan {i>dingbats<i} alih-alih teks yang sebenarnya.
TYPE_TEXT_VARIATION_URI
Varian TYPE_CLASS_TEXT untuk memasukkan URL web dan Uniform Resource lainnya ID (URI).
TYPE_TEXT_FLAG_AUTO_COMPLETE
Varian TYPE_CLASS_TEXT untuk memasukkan teks yang diisi otomatis oleh aplikasi dari kamus, penelusuran, atau fasilitas lainnya.

Sembunyikan inputType dengan konstanta yang sesuai saat menguji varian ini. Tujuan konstanta mask yang tersedia tercantum dalam dokumentasi referensi untuk InputType.

Mengirim teks ke aplikasi

Saat pengguna memasukkan teks dengan IME, Anda dapat mengirim teks ke aplikasi dengan mengirimkan peristiwa tombol atau dengan mengedit teks di sekitar kursor dalam kolom teks aplikasi. Dalam kedua kasus tersebut, gunakan instance InputConnection untuk mengirimkan teks. Untuk mendapatkan instance ini, panggil InputMethodService.getCurrentInputConnection().

Mengedit teks di sekitar kursor

Saat Anda menangani pengeditan teks yang ada, beberapa metode yang berguna di BaseInputConnection adalah sebagai berikut:

getTextBeforeCursor()
Menampilkan CharSequence berisi jumlah karakter yang diminta sebelum posisi kursor saat ini.
getTextAfterCursor()
Mengembalikan CharSequence yang berisi jumlah karakter yang diminta setelah posisi kursor saat ini.
deleteSurroundingText()
Menghapus jumlah karakter yang ditentukan sebelum dan setelah posisi kursor saat ini.
commitText()
Meng-commit CharSequence ke kolom teks dan menetapkan posisi kursor baru.

Misalnya, cuplikan berikut menunjukkan cara mengganti empat karakter di sebelah kiri kursor dengan teks "Halo!":

Kotlin

currentInputConnection.also { ic: InputConnection ->
    ic.deleteSurroundingText(4, 0)
    ic.commitText("Hello", 1)
    ic.commitText("!", 1)
}

Java

InputConnection ic = getCurrentInputConnection();
ic.deleteSurroundingText(4, 0);
ic.commitText("Hello", 1);
ic.commitText("!", 1);

Mendukung penulisan teks sebelum melakukan commit

Jika IME memprediksi teks atau memerlukan beberapa langkah untuk membuat glyph atau kata, Anda dapat menampilkan progres di kolom teks hingga pengguna meng-commit kata, lalu Anda dapat mengganti komposisi dengan teks yang lengkap. Anda dapat memberikan perlakuan khusus pada teks dengan menambahkan span saat meneruskannya ke setComposingText().

Cuplikan berikut menunjukkan cara menampilkan progres di kolom teks:

Kotlin

currentInputConnection.also { ic: InputConnection ->
    ic.setComposingText("Composi", 1)
    ic.setComposingText("Composin", 1)
    ic.commitText("Composing ", 1)
}

Java

InputConnection ic = getCurrentInputConnection();
ic.setComposingText("Composi", 1);
ic.setComposingText("Composin", 1);
ic.commitText("Composing ", 1);

Mengintersep peristiwa tombol hardware

Meskipun jendela metode input tidak memiliki fokus yang eksplisit, jendela ini menerima peristiwa tombol hardware terlebih dahulu dan dapat memakainya atau meneruskannya ke aplikasi. Misalnya, Anda mungkin ingin menggunakan tombol arah untuk menavigasi dalam UI guna memilih kandidat selama penulisan. Anda mungkin juga ingin menekan tombol kembali untuk menutup dialog yang berasal dari metode input jendela.

Untuk mencegat tombol hardware, ganti onKeyDown() dan onKeyUp().

Panggil metode super() untuk kunci yang tidak ingin Anda tangani sendiri.

Membuat subjenis IME

Subjenis memungkinkan IME mengekspos beberapa mode input dan bahasa yang didukung oleh IME. Subjenis dapat mewakili hal berikut:

  • Lokalitas, seperti en_US atau fr_FR
  • Mode input, seperti suara, keyboard, atau tulisan tangan
  • Gaya, formulir, atau properti input lain khusus IME, seperti tata letak keyboard 10 tombol atau QWERTY

Mode dapat berupa teks apa pun, seperti "keyboard" atau "voice". Subjenis juga dapat mengekspos kombinasi tersebut.

Informasi subjenis digunakan untuk dialog pengalih IME yang tersedia dari bilah notifikasi dan untuk setelan IME. Informasi ini juga memungkinkan framework memunculkan subjenis IME tertentu secara langsung. Saat Anda mem-build IME, gunakan fasilitas subjenis, karena fasilitas tersebut membantu pengguna mengidentifikasi dan beralih antar-bahasa dan antar-mode IME.

Definisikan subjenis dalam salah satu file resource XML metode input, dengan menggunakan Elemen <subtype>. Cuplikan kode berikut menentukan IME dengan dua subjenis: subjenis keyboard untuk lokalitas bahasa Inggris AS dan subjenis keyboard lainnya untuk bahasa Prancis lokal untuk Prancis:

<input-method xmlns:android="http://schemas.android.com/apk/res/android"
        android:settingsActivity="com.example.softkeyboard.Settings"
        android:icon="@drawable/ime_icon">
    <subtype android:name="@string/display_name_english_keyboard_ime"
            android:icon="@drawable/subtype_icon_english_keyboard_ime"
            android:languageTag="en-US"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="somePrivateOption=true" />
    <subtype android:name="@string/display_name_french_keyboard_ime"
            android:icon="@drawable/subtype_icon_french_keyboard_ime"
            android:languageTag="fr-FR"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="someVariable=30,someInternalOption=false" />
    <subtype android:name="@string/display_name_german_keyboard_ime" ... />
</input-method>

Untuk memastikan subjenis diberi label dengan benar di UI, gunakan `%s` untuk mendapatkan label subjenis yang sama dengan label lokal subjenis. Hal ini ditunjukkan dalam dua cuplikan kode berikutnya. Tujuan cuplikan pertama menunjukkan bagian dari file XML metode input:

<subtype
    android:label="@string/label_subtype_generic"
    android:imeSubtypeLocale="en_US"
    android:icon="@drawable/icon_en_us"
    android:imeSubtypeMode="keyboard" />

Cuplikan berikutnya adalah bagian dari file strings.xml IME. Resource string label_subtype_generic, yang digunakan oleh definisi UI metode input untuk menyetel label subjenis didefinisikan sebagai berikut:

<string name="label_subtype_generic">%s</string>

Setelan ini membuat nama tampilan subjenis cocok dengan setelan lokal. Misalnya, dalam lokalitas bahasa Inggris, nama tampilan adalah “English (United States)”.

Memilih subjenis IME dari baris notifikasi

Sistem Android mengelola semua subjenis yang ditampilkan oleh semua IME. Subjenis IME diperlakukan sebagai mode IME milik mereka. Pengguna dapat membuka dari panel notifikasi atau aplikasi Setelan ke menu subjenis IME yang tersedia, seperti yang ditunjukkan pada gambar berikut:

Gambar yang menampilkan opsi Bahasa & masukkan menu Sistem
Gambar 4. Opsi Bahasa & input menu sistem.

Memilih subjenis IME dari Setelan Sistem

Pengguna juga dapat mengontrol penggunaan subjenis di panel setelan Bahasa & input di setelan sistem:

Gambar yang menampilkan menu pilihan Bahasa
Gambar 5. Menu sistem Bahasa

Beralih antar-subjenis IME

Anda dapat mengizinkan pengguna beralih dengan mudah di antara subjenis IME dengan memberikan tombol pengalih, seperti ikon bahasa berbentuk globe di keyboard. Hal ini meningkatkan kegunaan keyboard dan memudahkan pengguna. Untuk mengaktifkan pengalihan ini, lakukan langkah-langkah berikut:

  1. Deklarasikan supportsSwitchingToNextInputMethod = "true" dalam file resource XML metode input. Deklarasi Anda harus terlihat mirip dengan cuplikan kode berikut:
    <input-method xmlns:android="http://schemas.android.com/apk/res/android"
            android:settingsActivity="com.example.softkeyboard.Settings"
            android:icon="@drawable/ime_icon"
            android:supportsSwitchingToNextInputMethod="true">
  2. Panggil metode shouldOfferSwitchingToNextInputMethod().
  3. Jika metode menampilkan nilai true, tampilkan tombol pengalih.
  4. Ketika pengguna mengetuk tombol alih, panggil switchToNextInputMethod(), meneruskan ke false (salah). Nilai false memberi tahu sistem untuk memperlakukan semua subjenis secara sama, apa pun IME yang miliknya. Sistem harus melewati seluruh subjenis dalam IME saat ini jika menentukan nilai true.

Pertimbangan IME umum

Berikut adalah hal lain yang perlu dipertimbangkan saat Anda menerapkan IME:

  • Berikan cara bagi pengguna untuk menetapkan opsi langsung dari UI IME.
  • Berikan cara bagi pengguna untuk beralih ke IME yang berbeda langsung dari UI metode input, karena mungkin ada beberapa IME yang terinstal di perangkat tersebut.
  • Munculkan UI IME dengan cepat. Pramuat atau muat resource besar on demand agar pengguna dapat langsung melihat IME setelah mereka mengetuk kolom teks. Resource dan tampilan cache untuk pemanggilan metode input berikutnya.
  • Merilis alokasi memori besar segera setelah jendela metode input disembunyikan, sehingga bahwa aplikasi memiliki cukup memori untuk dijalankan. Menggunakan pesan tertunda untuk melepaskan resource jika IME disembunyikan selama beberapa detik.
  • Pastikan pengguna dapat memasukkan karakter sebanyak mungkin untuk bahasa atau lokalitas yang terkait dengan IME. Pengguna mungkin menggunakan tanda baca dalam sandi atau nama pengguna, sehingga IME Anda harus menyediakan banyak karakter yang berbeda agar pengguna dapat memasukkan sandi dan mengakses perangkat.