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 ListActivity
biết cái mà ListView
chú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ừ EditText
và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 ListAdapter
và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 OnKeyListener
sẽ 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 TextWatcher
vào EditText
và chuyển ListAdapter
Filter
yêu cầu bộ lọc mỗi khi văn bản thay đổi. Hãy nhớ để loại bỏ TextWatcher
trong 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);
}