我目前正在尝试扩展我在http://jsharkey.org/blog/2008/08/18/separating-lists-with-headers-in-android-09/上找到的示例。
我首先通过创建一个EditText作为我的搜索栏来扩展它,然后按照一些教程来实现Filter函数。我要做的是当用户输入文本时,如果该部分具有匹配的文本,则返回该部分及其所有子项。如果搜索子项,则返回其部分和与约束匹配的子项。我的功能在没有任何部分时起作用,但它对部分根本不起作用。
非常感谢帮助。
main_list.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.myapplication">
<EditText
android:id="@+id/search_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:drawableRight="@android:drawable/ic_menu_search"
android:hint="Search"
android:lines="1"
android:maxLines="1"
android:maxWidth="100dp"
android:minWidth="300dp"
android:singleLine="true"/>
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/search_text"/>
</RelativeLayout>
然后我修改了一些主要活动,以便我可以实现搜索栏。
ListSample.java
public class ListSample extends Activity {
SeparatedListAdapter adapter;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main_list);
ListView listView = (ListView) findViewById(R.id.list_view);
EditText inputSearch = (EditText) findViewById(R.id.search_text);
List<String> america = new ArrayList<>();
america.add("Chicago");
america.add("Washington");
List<String> australia = new ArrayList<>();
australia.add("Sydney");
australia.add("Melbourne");
australia.add("Perth");
List<String> combined = new ArrayList<>();
combined.addAll(america);
combined.addAll(australia);
// create our list and custom adapter
adapter = new SeparatedListAdapter(this, combined);
adapter.addSection("America", new ArrayAdapter<String>(this,
R.layout.list_item, america));
adapter.addSection("Australia", new ArrayAdapter<String>(this,
R.layout.list_item, australia));
listView.setAdapter(adapter);
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
}
过滤功能
@Override
public Filter getFilter() {
if(filter == null){
filter = new dataFilter();
}
return filter;
}
private class dataFilter extends Filter{
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
constraint = constraint.toString().toLowerCase(Locale.getDefault());
ArrayList<String> filterList = new ArrayList<String>();
if(constraint != null && constraint.length() > 0){
for(int i =0; i < originalDataFilterList.size(); i++){
if(originalDataFilterList.get(i).toLowerCase().contains(constraint.toString().toLowerCase())){
filterList.add(originalDataFilterList.get(i));
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = originalDataFilterList.size();
results.values = originalDataFilterList;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results){
originalData = (ArrayList<String>)results.values;
notifyDataSetChanged();
}
}
答案 0 :(得分:0)
目前,您的过滤结果存储在originalData
数组中,没有子节信息。代码未修改headers
适配器和sections
地图,这些地图单独存储在SeparatedListAdapter
中,因此当您更改过滤器并调用notifyDataSetChanged()
时,不会发生任何更改。
而不是创建combined
列表并将其传递给SeparatedListAdapter
,而是使用这个&#39; flat&#39;过滤列表,您可能需要在过滤期间迭代sections
地图及其适配器,存储过滤结果,然后getItem()
,getCount()
,getViewTypeCount()
,需要重写getItemViewType()
,isEnabled()
,getView()
和getItemId()
方法以考虑结果。
有很多方法可以实现这一点。例如,为避免每次过滤器更改时重新创建sections
和headers
数组,您可以计算列表视图position
的映射并将其存储到相应的标题和子项(按存储标题/适配器的偏移量和子项的位置),以便相应地通过getItem()
等方法进行应用。您还需要计算总计数(按getCount()
检索)。