Giới thiệu
Bài viết này minh họa khái niệm cơ bản về việc tạo một bàn phím mềm (Input Method Editor - IME) tùy chỉnh cho Android sử dụng Kotlin. Lưu ý: Đây chỉ là ví dụ đơn giản hiển thị EditText, không phải IME hoàn chỉnh.
Các bước thực hiện
Bước 1: Tạo dự án mới
Tạo project: File → New Project.
Bước 2: Thiết kế giao diện (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp" />
<Button
android:id="@+id/btnShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/editText"
android:layout_centerInParent="true"
android:layout_marginTop="5dp"
android:onClick="showText"
android:text="SHOW TEXT" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btnShow"
android:layout_centerInParent="true"
android:layout_marginTop="10dp"
android:textColor="@android:color/background_dark"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Soft KeyBoard"
android:textColor="@android:color/holo_red_light"
android:textSize="24sp"
android:textStyle="bold" />
</RelativeLayout>
Bước 3: Xử lý logic (src/MainActivity.kt)
import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
private lateinit var editText: EditText
private lateinit var textView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
editText = findViewById(R.id.editText)
textView = findViewById(R.id.textView)
}
fun showText(view: View) {
val newText = editText.text.toString()
textView.text = newText
}
}
Bước 4: Cấu hình Manifest (androidManifest.xml)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.com.q11">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Chạy ứng dụng
Kết nối thiết bị, nhấn Run. Nhập text vào EditText, nhấn "SHOW TEXT" để hiển thị nội dung lên TextView. Bàn phím hệ thống sẽ tự động hiện ra khi focus vào EditText.
Phát triển IME thực sự (Custom Keyboard)
Ví dụ trên chỉ dùng bàn phím hệ thống. Để tạo bàn phím tùy chỉnh hoàn chỉnh, bạn cần:
1. Tạo service kế thừa InputMethodService
import android.inputmethodservice.InputMethodService
import android.inputmethodservice.Keyboard
import android.inputmethodservice.KeyboardView
import android.view.View
class CustomKeyboardService : InputMethodService(), KeyboardView.OnKeyboardActionListener {
private lateinit var keyboardView: KeyboardView
private lateinit var keyboard: Keyboard
override fun onCreateInputView(): View {
keyboardView = layoutInflater.inflate(R.layout.keyboard_view, null) as KeyboardView
keyboard = Keyboard(this, R.xml.qwerty_keyboard)
keyboardView.keyboard = keyboard
keyboardView.setOnKeyboardActionListener(this)
return keyboardView
}
override fun onKey(primaryCode: Int, keyCodes: IntArray) {
// Xử lý phím bấm, gửi text đến app
currentInputConnection?.commitText(primaryCode.toChar().toString(), 1)
}
// ... implement các method khác
}
2. Định nghĩa layout bàn phím (res/layout/keyboard_view.xml)
<android.inputmethodservice.KeyboardView
xmlns:android="https://schemas.android.com/apk/res/android"
android:id="@+id/keyboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:keyPreviewLayout="@layout/key_preview" />
3. Định nghĩa layout phím (res/xml/qwerty_keyboard.xml)
<Keyboard xmlns:android="https://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
android:keyHeight="60dp">
<Row>
<Key android:codes="113" android:keyLabel="q" />
<Key android:codes="119" android:keyLabel="w" />
<Key android:codes="101" android:keyLabel="e" />
<Key android:codes="114" android:keyLabel="r" />
<Key android:codes="116" android:keyLabel="t" />
<Key android:codes="121" android:keyLabel="y" />
<Key android:codes="117" android:keyLabel="u" />
<Key android:codes="105" android:keyLabel="i" />
<Key android:codes="111" android:keyLabel="o" />
<Key android:codes="112" android:keyLabel="p" />
</Row>
<!-- Các row khác... -->
</Keyboard>
4. Khai báo trong Manifest
<service android:name=".CustomKeyboardService"
android:label="Custom Keyboard"
android:permission="android.permission.BIND_INPUT_METHOD">
<meta-data android:name="android.view.im" android:resource="@xml/method" />
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
</service>
5. File metadata (res/xml/method.xml)
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="https://schemas.android.com/apk/res/android">
<subtype
android:label="English"
android:imeSubtypeLocale="en_US"
android:imeSubtypeMode="keyboard" />
</input-method>
Lưu ý
- Phát triển IME phức tạp, cần xử lý: multi-touch, gesture, prediction, auto-correction, themes, multiple languages.
- Tham khảo source code LatinIME (AOSP) hoặc thư viện KeyboardView (deprecated API 29+).
- Từ API 29,
KeyboardViewdeprecated, nên dùng custom View tự vẽ hoặc thư viện third-party.