ตัวอย่างนี้สาธิตวิธีทำให้ EditText ภายใน ListItem สามารถโฟกัสและพิมพ์ได้ โดยตั้งค่า android:descendantFocusability="beforeDescendants" ให้ ListView
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
Android Studio → New Project → Empty Activity
ขั้นตอนที่ 2: 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="4dp"
tools:context=".MainActivity">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="beforeDescendants" />
</LinearLayout>
ขั้นตอนที่ 3: Layout รายการ (res/layout/list_item.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="4dp">
<EditText
android:id="@+id/etItemCaption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:singleLine="true"
android:hint="Enter text..." />
</LinearLayout>
ขั้นตอนที่ 4: โค้ดหลัก (MainActivity.kt)
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.EditText
import android.widget.ListView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
private lateinit var listView: ListView
private lateinit var adapter: MyAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "Focusable EditText in ListView"
listView = findViewById(R.id.listView)
// 🔑 จุดสำคัญ: อนุญาตให้ Child View โฟกัสได้
listView.itemsCanFocus = true
adapter = MyAdapter(this)
listView.adapter = adapter
}
private inner class MyAdapter(private val context: Context) : BaseAdapter() {
private val inflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
private val items = mutableListOf()
init {
// ข้อมูลตัวอย่าง 7 รายการ
repeat(7) { items.add("Item $it") }
}
override fun getCount(): Int = items.size
override fun getItem(position: Int): Any = items[position]
override fun getItemId(position: Int): Long = position.toLong()
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
var view = convertView
val holder: ViewHolder
if (view == null) {
holder = ViewHolder()
view = inflater.inflate(R.layout.list_item, parent, false)
holder.etCaption = view.findViewById(R.id.etItemCaption)
view.tag = holder
} else {
holder = view.tag as ViewHolder
}
// ตั้งค่าข้อความ
holder.etCaption.setText(items[position])
holder.etCaption.tag = position // เก็บ position ไว้
// 🔑 จุดสำคัญ: บันทึกข้อมูลเมื่อโฟกัสหาย (Lost Focus)
holder.etCaption.setOnFocusChangeListener { v, hasFocus ->
if (!hasFocus) {
val pos = v.tag as Int
items[pos] = v.text.toString()
}
}
return view!!
}
private class ViewHolder {
lateinit var etCaption: EditText
}
}
}
🔑 จุดสำคัญ 2 อย่าง
- ListView XML:
android:descendantFocusability="beforeDescendants" - Code:
listView.itemsCanFocus = true
⚠️ ข้อควรระวัง
- Soft Keyboard อาจบัง ListItem → ใช้
android:windowSoftInputMode="adjustPan|adjustResize"ใน Manifest - ListView แบบนี้ไม่เหมาะกับรายการเยอะ (Performance) → ควรใช้ RecyclerView แทน
- ต้องจัดการ Focus แบบ Manual สำหรับการ Scroll
AndroidManifest.xml (Activity Config)
<activity
android:name=".MainActivity"
android:windowSoftInputMode="adjustResize">
...
</activity>
ทดสอบ
- รันแอป → แสดง ListView 7 รายการ แต่ละรายการมี EditText
- กดที่ EditText ใดๆ → Keyboard ขึ้น พิมพ์ได้
- กด Enter/นอกพื้นที่ → ข้อมูลจะบันทึกลง List อัตโนมัติ