2010-03-03 39 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> 

我希望這個代碼將不會有助於實現自定義搜索和過濾列表視圖