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 ý
windowTokencần thiết để xác định window chứa view.- Flag
0nghĩa là ẩn bình thường. Có thể dùngInputMethodManager.HIDE_NOT_ALWAYS. - Trên Android 11+, có thể dùng
WindowInsetsControllerđể kiểm soát IME tốt hơn.