Trước tiên, bạn cần tạo một bố cục XML có cả EditText và ListView.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<!-- Pretty hint text, and maxLines -->
<EditText android:id="@+building_list/search_box"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="type to filter"
android:inputType="text"
android:maxLines="1"/>
<!-- Set height to 0, and let the weight param expand it -->
<!-- Note the use of the default ID! This lets us use a
ListActivity still! -->
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
/>
</LinearLayout>
Điều này sẽ đặt mọi thứ ra một cách chính xác, với một EditText đẹp phía trên ListView. Tiếp theo, tạo ListActivity như bình thường, nhưng thêm một setContentView()cuộc gọi trong onCreate()phương thức để chúng tôi sử dụng bố cục được khai báo gần đây của chúng tôi. Hãy nhớ rằng chúng tôi đã ID ListViewđặc biệt, với android:id="@android:id/list". Điều này cho phép ListActivitybiết cái mà ListViewchúng ta muốn sử dụng trong bố cục khai báo của chúng ta.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.filterable_listview);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
getStringArrayList());
}
Chạy ứng dụng bây giờ sẽ hiển thị trước đó của bạn ListView, với một hộp đẹp ở trên. Để làm cho hộp đó làm một cái gì đó, chúng ta cần lấy đầu vào từ nó và làm cho bộ lọc đầu vào đó lọc danh sách. Trong khi nhiều người đã cố gắng thực hiện việc này một cách thủ công, hầu hết ListView Adapter các lớp đều đi kèm với một Filterđối tượng có thể được sử dụng để thực hiện quá trình lọc tự động. Chúng ta chỉ cần ống đầu vào từ EditTextvào Filter. Hóa ra là khá dễ dàng. Để chạy thử nghiệm nhanh, hãy thêm dòng này vào onCreate()cuộc gọi của bạn
adapter.getFilter().filter(s);
Lưu ý rằng bạn sẽ cần lưu của bạn ListAdaptervào một biến để thực hiện công việc này - Tôi đã lưu ArrayAdapter<String>từ trước đó vào một biến có tên là 'bộ chuyển đổi'.
Bước tiếp theo là lấy đầu vào từ EditText. Điều này thực sự cần một chút suy nghĩ. Bạn có thể thêm một OnKeyListener()vào EditText. Tuy nhiên, người nghe này chỉ nhận được một số sự kiện quan trọng . Ví dụ: nếu người dùng nhập 'wyw', văn bản dự đoán có thể sẽ đề xuất 'mắt'. Cho đến khi người dùng chọn 'wyw' hoặc 'eye', bạn OnKeyListenersẽ không nhận được một sự kiện quan trọng. Một số có thể thích giải pháp này, nhưng tôi thấy nó bực bội. Tôi muốn mọi sự kiện quan trọng, vì vậy tôi có quyền lựa chọn lọc hoặc không lọc. Giải pháp là a TextWatcher. Chỉ cần tạo và thêm a TextWatchervào EditTextvà chuyển ListAdapter Filteryêu cầu bộ lọc mỗi khi văn bản thay đổi. Hãy nhớ để loại bỏ TextWatchertrong OnDestroy()! Đây là giải pháp cuối cùng:
private EditText filterText = null;
ArrayAdapter<String> adapter = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.filterable_listview);
filterText = (EditText) findViewById(R.id.search_box);
filterText.addTextChangedListener(filterTextWatcher);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
getStringArrayList());
}
private TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
adapter.getFilter().filter(s);
}
};
@Override
protected void onDestroy() {
super.onDestroy();
filterText.removeTextChangedListener(filterTextWatcher);
}