2010-03-03 107 views
20

Làm cách nào để tạo thanh tìm kiếm trong khi tôi đang nhập kết quả được hiển thị trong ListView mà tôi đang tìm kiếm?Danh sách tìm kiếm Android khi nhập

Ví dụ: tôi có chế độ xem danh sách với 20 chuỗi. Tôi bấm phím tìm kiếm và xuất hiện thanh. Tôi muốn khi tôi nhập 3 từ trở lên, tìm kiếm bắt đầu chạy hiển thị kết quả trong chế độ xem danh sách (dưới dạng bộ lọc: chỉ hiển thị các chuỗi trong danh sách khớp với những gì tôi nhập)

+1

Một ví dụ rất tốt là tại http://www.androidpeople.com/android-listview-searchbox-sort-items – amithgc

+0

Giải pháp này tạo ra một mảng dữ liệu mới và một ListAdapter mới cho mỗi ký tự được nhập. Tôi không thể tin rằng đây là cách tốt nhất để làm điều đó .. –

Trả lời

13

Bạn không thể làm điều này với thanh tìm kiếm. Nhưng listview có một khả năng để filter on key pressed, giống như nó được thực hiện trong danh bạ. Người dùng chỉ cần bắt đầu nhập và danh sách được lọc sau đó. Lọc không thực sự giống như tìm kiếm. Nếu danh sách của bạn chứa từ foo ở đâu đó và bạn gõ oo foo sẽ được lọc ra, nhưng nếu bạn gõ fo nó sẽ ở lại ngay cả khi mục danh sách là thanh cuộc gọi foo.

Bạn chỉ cần phải kích hoạt nó:

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

Tôi không biết làm thế nào điều này được thực hiện nếu bạn không có một bàn phím cứng. Tôi đang sử dụng droid và bắt đầu gõ bắt đầu danh sách để lọc và chỉ hiển thị kết quả phù hợp.

+0

ok, nó không phải là chính xác những gì tôi cần nhưng đó là một giải pháp tốt. cảm ơn! – xger86x

1

Cách tốt nhất là sử dụng trong thanh tìm kiếm hoặc SearchManager bằng cách ghi đè onSearchRequested trong một hoạt động có thể tìm kiếm. Bạn có thể đặt nguồn dữ liệu để tìm kiếm để nhận được kết quả thả xuống tự động hoặc bạn chỉ có thể nhập vào từ người dùng và tìm kiếm sau. Dưới đây là một tổng quan tốt của SearchManager là một Ngoài ra có một bản demo làm việc trong Demo API dự án com.example.android.apis.app.SearchQueryResult

@Override 
public boolean onSearchRequested() { 
+2

có .. nhưng tôi không muốn có được một kết quả thả xuống tự động. Tôi muốn danh sách nơi tôi đang tìm kiếm tự động làm mới với kết quả tìm kiếm trong khi tôi đang nhập, không xuất hiện trình đơn thả xuống. Cảm ơn! – xger86x

+0

ahh, xin lỗi tôi đã hiểu nhầm câu hỏi. Nếu không xây dựng chế độ xem tùy chỉnh của riêng bạn và cố gắng chuyển đến danh sách các sự kiện nhấn phím, tôi không biết bất kỳ điều gì tốt hơn ngoài tầm tay. –

9

Tôi đã sử dụng EditText để thực hiện công việc.

Trước tiên tôi tạo ra hai bản sao của mảng để giữ danh sách các dữ liệu để tìm kiếm:

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

Một khi tôi đã có dữ liệu danh sách của tôi từ nơi nào đó, tôi sao chép nó:

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

và sử dụng một số SimpleAdapter để hiển thị phiên bản hiển thị (sao chép) của dữ liệu của tôi:

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); 

Sau đó tôi đã thêm một TextWatcher đến EditText phản hồi sự kiện afterTextChanged bằng cách xóa phiên bản hiển thị của danh sách và sau đó chỉ thêm lại các mục từ danh sách khác đáp ứng tiêu chí tìm kiếm (trong trường hợp này trường "reg" chứa chuỗi tìm kiếm). Khi danh sách hiển thị được điền với danh sách được lọc, tôi chỉ cần gọi notifyDataSetChanged trên danh sách SimpleAdapter của danh sách.

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 ... 
}); 

Hy vọng điều này hữu ích cho người khác.

+0

+1 tôi đang tìm kiếm điều này .... :) – BBdev

19

Tôi tin rằng đây là những gì bạn đang tìm kiếm:

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

Có Hoạt động của bạn thực hiện SearchView.OnQueryTextListener

và thêm các phương pháp sau:

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

Có! Tốt hơn nhiều. –

+0

Bạn cũng phải thêm 'searchView.setOnQueryTextListener (this);' vào onCreateOptionsMenu. – bvmobileapps

4

Sử dụng đoạn mã sau để thực hiện danh sách tìm kiếm và bộ lọc trong 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); 
    } 

} 

Tuỳ chỉnh Giá trị chuyển đổi: 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> 

Tôi hy vọng mã này sẽ sẽ hữu ích khi triển khai chế độ xem danh sách tìm kiếm và bộ lọc tùy chỉnh

Các vấn đề liên quan