我正在写一本字典应用程序。我的搜索屏幕非常简单:Activity
的中心是应用程序的徽标,并且与屏幕底部对齐的是搜索框。当搜索框获得焦点时,软键盘会弹出,搜索框会在其上方移动。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView android:id="@+id/search_logo"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:src="@drawable/logo_transparent"
android:layout_centerInParent="true"
android:contentDescription="@string/desc_logo"
/>
<EditText android:id="@+id/search_fld"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/textbox"
android:inputType="text"
android:hint="@string/search_hint"
android:padding="10dp"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>
只要用户输入一个字母,我就会在Lucene中查询匹配的条目。我希望搜索框顶部的视图对于每个键入(或删除)的字母都是动态更新的ListView
,但是如何从这个XML布局中执行此操作?这种设计的正确方法是什么?
答案 0 :(得分:3)
以下是最终将引导您回答的指针。
将textwatcher
添加到您要在其中编写搜索字词的编辑字段中。
txtSearch.addTextChangedListener(textWatcher);
在textwatcher的afterTextChanged
方法中,您需要一个过滤器,其中在searchfield中键入的字符作为参数,以过滤掉搜索结果。
private TextWatcher textWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
adapter.getFilter().filter(s);
adapter.notifyDataSetChanged();
}
};
以下是我用于过滤目的的课程。
/*
* Class that implements filtering functionality.
*/
public class MyFilter extends Filter {
public MyFilter(ArrayList<CustomerListRow> data) {
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
FilterResults result = new FilterResults();
if (constraint != null && constraint.toString().length() > 0) {
ArrayList<CustomerListRow> filt = new ArrayList<CustomerListRow>();
for (int i = 0; i < arrayListCopy.size(); i++) {
CustomerListRow each = arrayListCopy.get(i);
if (each.getName().toLowerCase().contains(constraint)) {
filt.add(each);
}
}
result.count = filt.size();
result.values = filt;
} else {
synchronized (this) {
result.count = arrayListCopy.size();
result.values = arrayListCopy;
}
}
return result;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
ArrayList<CustomerListRow> filtered = (ArrayList<CustomerListRow>) results.values;
clear();
int size = filtered.size();
for (int i = 0; i < size; i++) {
add(filtered.get(i));
}
notifyDataSetInvalidated();
}
}
您需要创建一个适配器,您将传递完整列表,最终将传递给过滤器。 以下是我的适配器类的构造函数。
public MyAdapter(Context context, int textViewResourceId,
List<CustomerListRow> objects) {
super(context, textViewResourceId, objects);
this.context = context;
inflator = (LayoutInflater) context
.getSystemService(LAYOUT_INFLATER_SERVICE);
list = (ArrayList<CustomerListRow>) objects;
filter = new MyFilter(list);
arrayListCopy.addAll(list);
}
答案 1 :(得分:1)
解决方案似乎更直截了当。首先,为TextWatcher
创建EditText
。然后,在onTextChanged()
内,这就是你所做的:
clear()
。notifyDataSetChanged()
。