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

Cách ẩn bàn phím mềm khi click ra ngoài EditText trên Android bằng Kotlin

Giới thiệu

Hướng dẫn này trình bày cách ẩn bàn phím mềm (soft keyboard) khi người dùng click ra ngoài EditText (tức là focus lost) trên Android sử dụng InputMethodManager và Kotlin.

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"?>
<LinearLayout 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"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context="MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:hint="Enter text here"
        android:textColor="@android:color/background_dark"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:onClick="setText"
        android:text="Set Text"
        android:textStyle="bold" />

</LinearLayout>

Bước 3: Xử lý logic (src/MainActivity.kt)

import android.content.Context
import android.os.Bundle
import android.view.View
import android.view.inputmethod.InputMethodManager
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)
        title = "KotlinApp"

        editText = findViewById(R.id.editText)
        textView = findViewById(R.id.textView)
    }

    fun setText(view: View) {
        val newText = editText.text.toString()
        textView.text = newText
        closeKeyBoard()
    }

    private fun closeKeyBoard() {
        val view = currentFocus
        if (view != null) {
            val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm.hideSoftInputFromWindow(view.windowToken, 0)
        }
    }
}

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, bàn phím hiện ra. Nhấn nút "Set Text" sẽ ẩn bàn phím và hiển thị text lên TextView.

Cách ẩn bàn phím khi click ra ngoài (Touch outside)

Code trên chỉ ẩn khi nhấn nút. Để ẩn khi click bất kỳ đâu ngoài EditText, override dispatchTouchEvent:

override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
    if (ev.action == MotionEvent.ACTION_DOWN) {
        val view = currentFocus
        if (view is EditText) {
            val outRect = Rect()
            view.getGlobalVisibleRect(outRect)
            if (!outRect.contains(ev.rawX.toInt(), ev.rawY.toInt())) {
                view.clearFocus()
                val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                imm.hideSoftInputFromWindow(view.windowToken, 0)
            }
        }
    }
    return super.dispatchTouchEvent(ev)
}

Cách hiện đại: Extension function

// Extension function cho Activity/Fragment
fun Activity.hideKeyboard() {
    currentFocus?.let { view ->
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, 0)
    }
}

fun View.hideKeyboard() {
    val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(windowToken, 0)
}

// Sử dụng:
editText.setOnFocusChangeListener { _, hasFocus ->
    if (!hasFocus) hideKeyboard()
}

// Hoặc trong layout root:
rootLayout.setOnClickListener { hideKeyboard() }

Lưu ý

  • windowToken cần thiết để xác định window chứa view.
  • Flag 0 nghĩa là ẩn bình thường. Có thể dùng InputMethodManager.HIDE_NOT_ALWAYS.
  • Trên Android 11+, có thể dùng WindowInsetsController để kiểm soát IME tốt hơn.