SearchView là widget cho phép người dùng nhập từ khóa để lọc dữ liệu trong danh sách. Thường dùng kết hợp với ListView/RecyclerView và Adapter có hỗ trợ filtering.
Các bước triển khai
Bước 1: Tạo project mới
Bước 2: Layout activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<androidx.appcompat.widget.SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="Tìm kiếm..."
android:iconifiedByDefault="false" />
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginTop="8dp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Bước 3: MainActivity.java
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;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ListView listView;
private SearchView searchView;
private ArrayAdapter adapter;
private List dataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listView);
searchView = findViewById(R.id.searchView);
// Dữ liệu mẫu
dataList = new ArrayList<>(Arrays.asList(
"Java", "Android", "C Language", "C++ Language",
"Go Language", "Kotlin", "Python", "JavaScript",
"Dart", "Flutter", "React Native", "Swift"
));
// Adapter hỗ trợ filter
adapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, dataList);
listView.setAdapter(adapter);
// Cấu hình SearchView
searchView.setIconifiedByDefault(false); // Mở rộng mặc định
searchView.setQueryHint("Nhập từ khóa...");
searchView.clearFocus(); // Tránh focus tự động
// Listener tìm kiếm
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
// Khi nhấn Enter/search trên bàn phím
searchView.clearFocus();
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
// Lọc real-time khi gõ
adapter.getFilter().filter(newText);
return true;
}
});
// Click item
listView.setOnItemClickListener((parent, view, position, id) -> {
String item = adapter.getItem(position);
Toast.makeText(this, "Đã chọn: " + item, Toast.LENGTH_SHORT).show();
});
}
}
Giải thích OnQueryTextListener
- onQueryTextSubmit(query): Gọi khi user nhấn nút search/Enter. Trả về true nếu đã xử lý.
- onQueryTextChange(newText): Gọi real-time khi text thay đổi. Dùng adapter.getFilter().filter() để lọc.
Yêu cầu Adapter phải implement Filterable
ArrayAdapter mặc định đã implement Filterable. Nếu dùng custom adapter, phải override getFilter():
public class CustomAdapter extends BaseAdapter implements Filterable {
// ...
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
// Logic lọc dữ liệu ở background thread
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// Cập nhật dữ liệu và notifyDataSetChanged()
}
};
}
}
Chạy ứng dụng
Gõ từ khóa vào SearchView → ListView lọc real-time chỉ hiển thị item chứa từ khóa. Nhấn item → Toast hiển thị tên item.
Mở rộng: SearchView trong Toolbar/ActionBar
// menu/search_menu.xml
<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="Tìm kiếm"
android:icon="@android:drawable/ic_menu_search"
app:showAsAction="collapseActionView|ifRoom"
app:actionViewClass="androidx.appcompat.widget.SearchView" />
</menu>
// Activity
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
// Cấu hình searchView...
return true;
}