2010-03-03 37 views
20

如何在创建搜索栏的同时输入搜索结果显示在我正在搜索的ListView中?键入时的Android搜索列表

例如,我有一个包含20个字符串的列表视图。我按搜索键并出现栏。当我输入3个或更多字时,搜索开始运行,在列表视图中显示结果(作为过滤器:只显示列表中与我输入的字符串相匹配的字符串)

+1

一个很好的例子是在 http://www.androidpeople.com/android-listview-searchbox-sort-items – amithgc 2010-06-21 11:37:22

+0

将该溶液创建一个新的数据阵列和一个新ListAdapter为每个键入的字符。我不能相信这是做到这一点的最佳方式。 – 2010-08-26 14:06:58

回答

13

你不能用搜索栏做到这一点。但是,这个列表视图有可能会像filter on key pressed一样在联系人中完成。用户只需开始输入,然后列表就会被过滤。过滤并不像搜索。如果列表中包含foo某处,并且输入了oo,则foo将被过滤掉,但如果您键入fo,则即使列表项为call bar foo,它也会保留。

您只需启用它:

ListView lv = getListView(); 
lv.setTextFilterEnabled(true); 

我不知道这是怎么做,如果你没有硬件键盘。我使用的是机器人,并开始键入启动列表进行过滤,并只显示匹配的结果。

+0

好吧,这不完全是我需要的,但它是一个很好的解决方案。谢谢! – xger86x 2010-03-04 10:42:50

1

最好的方法是使用内置在搜索栏或SearchManager中,通过在可搜索的活动中重写onSearchRequested。您可以设置要搜索的数据源来获取结果的自动下拉列表,也可以接受用户的输入并搜索。这里是SearchManager一个很好的概述是 加有在API演示工作示范项目com.example.android.apis.app.SearchQueryResult

@Override 
public boolean onSearchRequested() { 
+2

是的..但我不想得到一个自动下拉结果。我想要在搜索结果的同时自动刷新自动刷新的列表,而不是出现下拉菜单。谢谢! – xger86x 2010-03-03 23:58:40

+0

啊,对不起,我误解了这个问题。如果没有建立自己的自定义视图并尝试跳到按键事件上的列表项,我不知道任何更好的手。 – 2010-03-04 00:04:13

9

我用EditText来完成这项工作。

首先,我创建数组的两个副本来保存数据的列表来搜索:

List<Map<String,String>> vehicleinfo; 
List<Map<String,String>> vehicleinfodisplay; 

一旦我从什么地方得到了我的列表数据,我把它复制:

for(Map<String,String>map : vehicleinfo) 
{ 
    vehicleinfodisplay.add(map); 
} 

并使用SimpleAdapter显示我的数据的显示器(复制)版本:

String[] from={"vehicle","dateon","dateoff","reg"}; 
int[] to={R.id.vehicle,R.id.vehicledateon,R.id.vehicledateoff,R.id.vehiclereg}; 
listadapter=new SimpleAdapter(c,vehicleinfodisplay,R.layout.vehiclelistrow,from,to); 
vehiclelist.setAdapter(listadapter); 

然后我添加了一个TextWatcherEditText,它通过清除列表的显示版本,然后仅添加符合搜索条件的其他列表中的项目(在本例中,“reg”字段包含搜索字符串)来响应afterTextChanged事件。一旦显示列表填充了过滤列表,我只需拨打列表SimpleAdapter上的notifyDataSetChanged即可。

searchbox.addTextChangedListener(new TextWatcher() 
{ 
    @Override 
    public void afterTextChanged(Editable s) 
    { 
     vehicleinfodisplay.clear(); 
     String search=s.toString(); 
     for(Map<String,String>map : vehicleinfo) 
     { 
      if(map.get("reg").toLowerCase().contains(search.toLowerCase())) 
       vehicleinfodisplay.add(map); 
      listadapter.notifyDataSetChanged(); 
     } 
    }; 
    ... other overridden methods can go here ... 
}); 

希望这对某人有帮助。

+0

+1我在找这个.... :) – BBdev 2012-09-24 05:32:56

19

我相信这是你在找什么:

http://www.java2s.com/Code/Android/2D-Graphics/ShowsalistthatcanbefilteredinplacewithaSearchViewinnoniconifiedmode.htm

让你的活动实施搜索查看。OnQueryTextListener

,并添加以下方法:

public boolean onQueryTextChange(String newText) { 
    if (TextUtils.isEmpty(newText)) { 
     mListView.clearTextFilter(); 
    } else { 
     mListView.setFilterText(newText.toString()); 
    } 
    return true; 
} 

public boolean onQueryTextSubmit(String query) { 
    return false; 
} 
+0

是的!好多了。 – 2013-04-03 19:46:41

+0

您还必须在onCreateOptionsMenu中添加'searchView.setOnQueryTextListener(this);'。 – bvmobileapps 2016-08-29 03:16:55

4

使用下面的代码来实现在Android的搜索和过滤列表:

SearchAndFilterList.java

public class SearchAndFilterList extends Activity { 

    private ListView mSearchNFilterLv; 

    private EditText mSearchEdt; 

    private ArrayList<String> mStringList; 

    private ValueAdapter valueAdapter; 

    private TextWatcher mSearchTw; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_search_and_filter_list); 

     initUI(); 

     initData(); 

     valueAdapter=new ValueAdapter(mStringList,this); 

     mSearchNFilterLv.setAdapter(valueAdapter); 

     mSearchEdt.addTextChangedListener(mSearchTw); 


    } 
    private void initData() { 

     mStringList=new ArrayList<String>(); 

     mStringList.add("one"); 

     mStringList.add("two"); 

     mStringList.add("three"); 

     mStringList.add("four"); 

     mStringList.add("five"); 

     mStringList.add("six"); 

     mStringList.add("seven"); 

     mStringList.add("eight"); 

     mStringList.add("nine"); 

     mStringList.add("ten"); 

     mStringList.add("eleven"); 

     mStringList.add("twelve"); 

     mStringList.add("thirteen"); 

     mStringList.add("fourteen"); 

     mSearchTw=new TextWatcher() { 

      @Override 
      public void onTextChanged(CharSequence s, int start, int before, int count) { 

       valueAdapter.getFilter().filter(s); 
      } 

      @Override 
      public void beforeTextChanged(CharSequence s, int start, int count, 
        int after) { 

      } 

      @Override 
      public void afterTextChanged(Editable s) { 

      } 
     }; 

    } 

    private void initUI() { 

     mSearchNFilterLv=(ListView) findViewById(R.id.list_view); 

     mSearchEdt=(EditText) findViewById(R.id.txt_search); 
    } 

} 

自定义值适配器: ValueAdapter.java

public class ValueAdapter extends BaseAdapter implements Filterable{ 

    private ArrayList<String> mStringList; 

    private ArrayList<String> mStringFilterList; 

    private LayoutInflater mInflater; 

    private ValueFilter valueFilter; 

    public ValueAdapter(ArrayList<String> mStringList,Context context) { 

     this.mStringList=mStringList; 

     this.mStringFilterList=mStringList; 

     mInflater=LayoutInflater.from(context); 

     getFilter(); 
    } 

    //How many items are in the data set represented by this Adapter. 
    @Override 
    public int getCount() { 

     return mStringList.size(); 
    } 

    //Get the data item associated with the specified position in the data set. 
    @Override 
    public Object getItem(int position) { 

     return mStringList.get(position); 
    } 

    //Get the row id associated with the specified position in the list. 
    @Override 
    public long getItemId(int position) { 

     return position; 
    } 

    //Get a View that displays the data at the specified position in the data set. 
    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     Holder viewHolder; 

     if(convertView==null) { 

      viewHolder=new Holder(); 

      convertView=mInflater.inflate(R.layout.list_item,null); 

      viewHolder.nameTv=(TextView)convertView.findViewById(R.id.txt_listitem); 

      convertView.setTag(viewHolder); 

     }else{ 

      viewHolder=(Holder)convertView.getTag(); 
     } 

      viewHolder.nameTv.setText(mStringList.get(position).toString()); 

      return convertView; 
    } 

    private class Holder{ 

     TextView nameTv; 
    } 

    //Returns a filter that can be used to constrain data with a filtering pattern. 
    @Override 
    public Filter getFilter() { 

     if(valueFilter==null) { 

      valueFilter=new ValueFilter(); 
     } 

     return valueFilter; 
    } 


    private class ValueFilter extends Filter { 


     //Invoked in a worker thread to filter the data according to the constraint. 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 

      FilterResults results=new FilterResults(); 

      if(constraint!=null && constraint.length()>0){ 

       ArrayList<String> filterList=new ArrayList<String>(); 

       for(int i=0;i<mStringFilterList.size();i++){ 

        if(mStringFilterList.get(i).contains(constraint)) { 

         filterList.add(mStringFilterList.get(i)); 

        } 
       } 


       results.count=filterList.size(); 

       results.values=filterList; 

      }else{ 

       results.count=mStringFilterList.size(); 

       results.values=mStringFilterList; 

      } 

      return results; 
     } 


     //Invoked in the UI thread to publish the filtering results in the user interface. 
     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint, 
       FilterResults results) { 

      mStringList=(ArrayList<String>) results.values; 

      notifyDataSetChanged(); 


     } 

    } 

} 

activity_search_and_filter_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" > 

    <EditText 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/txt_search" 
     tools:context=".SearchAndFilterList" 
     android:hint="Enter text to search" /> 
    <ListView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/list_view" 
     android:layout_below="@+id/txt_search"></ListView> 

</RelativeLayout> 

list_item.xml

<?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" > 
    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/txt_listitem"/> 

</RelativeLayout> 

AndroidManifext.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.searchandfilterlistview" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="8" 
     android:targetSdkVersion="15" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name=".SearchAndFilterList" 
      android:label="@string/title_activity_search_and_filter_list" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

我希望这个代码将不会有助于实现自定义搜索和过滤列表视图