Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách phát triển bàn phím mềm (Soft Keyboard) cho Android bằng Kotlin

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, KeyboardView deprecated, nên dùng custom View tự vẽ hoặc thư viện third-party.