บทนำ
ตัวอย่างนี้สาธิตการใช้ SearchView เพื่อค้นหาข้อมูลใน ListView แบบ Real-time filtering
ขั้นตอนที่ 1: สร้างโปรเจกต์
สร้างโปรเจกต์ Android ใหม่ใน Android Studio
ขั้นตอนที่ 2: 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">
<SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:iconifiedByDefault="false"
android:queryHint="Search fruits..." />
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/searchView"
android:divider="#ddd"
android:dividerHeight="1dp" />
</RelativeLayout>
ขั้นตอนที่ 3: MainActivity.kt
import android.os.Bundle
import android.widget.ArrayAdapter
import android.widget.ListView
import android.widget.SearchView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
private lateinit var searchView: SearchView
private lateinit var listView: ListView
private lateinit var adapter: ArrayAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "SearchView Demo"
searchView = findViewById(R.id.searchView)
listView = findViewById(R.id.listView)
// ข้อมูลตัวอย่าง
val fruits = arrayListOf(
"Apple", "Banana", "Pineapple", "Orange", "Mango",
"Grapes", "Lemon", "Melon", "Watermelon", "Papaya"
)
adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, fruits)
listView.adapter = adapter
// ตั้งค่า SearchView
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
// เมื่อกด Enter/Submit
if (!adapter.filter.filter(query)) {
Toast.makeText(this@MainActivity, "No match found for '$query'", Toast.LENGTH_SHORT).show()
}
return true
}
override fun onQueryTextChange(newText: String): Boolean {
// Real-time filtering ขณะพิมพ์
adapter.filter.filter(newText)
return true
}
})
// เคลียร์โฟกัสค้นหาเมื่อกด Back
searchView.setOnCloseListener {
adapter.filter.filter("")
false
}
}
}
ขั้นตอนที่ 4: Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.searchview">
<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>
SearchView Attributes สำคัญ
| Attribute | คำอธิบาย |
|---|---|
android:iconifiedByDefault | "false" = แสดงขยายเต็ม, "true" = แสดงไอคอนกดแล้วขยาย |
android:queryHint | ข้อความ Hint ในช่องค้นหา |
android:maxWidth | ความกว้างสูงสุด |
android:searchIcon | ไอคอนค้นหาแบบกำหนดเอง |
android:goIcon | ไอคอน Submit/Go |
android:voiceIcon | ไอคอน Voice Search |
ใช้กับ RecyclerView (แนวทางทันสมัย)
// ใน Adapter class FruitAdapter(private val fruitList: List) : RecyclerView.Adapter (), Filterable { private var filteredList = fruitList override fun getFilter(): Filter = object : Filter() { override fun performFiltering(constraint: CharSequence?): FilterResults { val results = FilterResults() if (constraint.isNullOrBlank()) { results.values = fruitList results.count = fruitList.size } else { val filtered = fruitList.filter { it.lowercase().contains(constraint.toString().lowercase()) } results.values = filtered results.count = filtered.size } return results } override fun publishResults(constraint: CharSequence?, results: FilterResults?) { filteredList = results?.values as List notifyDataSetChanged() } } // ... ViewHolder และ onBindViewHolder } // ใน Activity searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextChange(newText: String): Boolean { adapter.filter.filter(newText) return true } override fun onQueryTextSubmit(query: String): Boolean = false })
SearchView ใน Toolbar/ActionBar
<menu xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:title="Search"
android:icon="@android:drawable/ic_menu_search"
app:showAsAction="always|collapseActionView"
app:actionViewClass="androidx.appcompat.widget.SearchView" />
</menu>
// ใน Activity
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
val searchItem = menu.findItem(R.id.action_search)
val searchView = searchItem.actionView as SearchView
// ตั้งค่า listener เหมือนเดิม
return true
}