在listview中搜索部分内部

时间:2015-09-16 04:52:30

标签: java android listview

我目前正在尝试扩展我在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();

    }
}

1 个答案:

答案 0 :(得分:0)

目前,您的过滤结果存储在originalData数组中,没有子节信息。代码未修改headers适配器和sections地图,这些地图单独存储在SeparatedListAdapter中,因此当您更改过滤器并调用notifyDataSetChanged()时,不会发生任何更改。

而不是创建combined列表并将其传递给SeparatedListAdapter,而是使用这个&#39; flat&#39;过滤列表,您可能需要在过滤期间迭代sections地图及其适配器,存储过滤结果,然后getItem()getCount()getViewTypeCount(),需要重写getItemViewType()isEnabled()getView()getItemId()方法以考虑结果。

有很多方法可以实现这一点。例如,为避免每次过滤器更改时重新创建sectionsheaders数组,您可以计算列表视图position的映射并将其存储到相应的标题和子项(按存储标题/适配器的偏移量和子项的位置),以便相应地通过getItem()等方法进行应用。您还需要计算总计数(按getCount()检索)。