19

Làm cách nào để chuyển đổi dữ liệu tĩnh ArrayAdapter<String> thành số CursorAdapter để sử dụng Trình nghe đề xuất trong SearchView? tôi đã xây dựng các ArrayAdapter<String> từ dữ liệu tĩnh (allString)Chuyển đổi một ArrayAdapter thành CursorAdapter để sử dụng trong SearchView

ArrayAdapter<String> searchAdapter = new ArrayAdapter<String>(context, R.layout.listitem, allString); 

và tôi sử dụng nó cho một MultiAutoCompleteTextView mà hoạt động tốt trong các thiết bị với mức API ít hơn 11

MultiAutoCompleteTextView findTextView.setAdapter(searchAdapter); 

Tuy nhiên API mục tiêu của tôi là mức là 11 và dành cho API> 10 Tôi sử dụng một số ActionBar, trong đó tôi muốn có một SearchView thay thế.

Đây là những gì tôi đã thử: Nó hiển thị ActionBar với số nhúng SearchView nhưng không đưa ra bất kỳ đề xuất nào như trong MultiAutoCompleteTextView.

@Override 
public boolean onCreateOptionsMenu(Menu menu) {  
     MenuInflater inflater = getMenuInflater(); 

     if (android.os.Build.VERSION.SDK_INT > 10){ 
      inflater.inflate(R.menu.menu11, menu); 
      searchView = (SearchView) menu.findItem(R.id.MENU_SEARCH).getActionView(); 
      int[] to = {0}; 
      CursorAdapter cursorAdapter = new SimpleCursorAdapter(context, R.layout.listitem, null, allBusStopString, to); 
      searchView.setSuggestionsAdapter(cursorAdapter); 
      searchView.setOnSuggestionListener(new OnSuggestionListener() { 

       @Override 
       public boolean onSuggestionClick(int position) { 
        String selectedItem = (String)cursorAdapter.getItem(position); 
        Log.v("search view", selectedItem); 
        return false; 
       } 

       @Override 
       public boolean onSuggestionSelect(int position) { 
        return false; 
       } 
      }); 
     }else{ 
      inflater.inflate(R.menu.menu, menu); 
     } 

    return true; 
} 

Trả lời

28

Điều lạ lùng SearchView.setSuggestionsAdapter chỉ chấp nhận CursorAdapter.

Bạn có thể tạo MatrixCursor và điền dữ liệu đó vào dữ liệu từ mảng Chuỗi. Tôi hy vọng bạn có bộ sưu tập dữ liệu nhỏ.

Sau đó, chuyển con trỏ tới CursorAdapter.

String[] columnNames = {"_id","text"} 
    MatrixCursor cursor = new MatrixCursor(columnNames); 
    String[] array = getResources().getStringArray(R.array.allStrings); //if strings are in resources 
    String[] temp = new String[2]; 
    int id = 0; 
    for(String item : array){ 
     temp[0] = Integer.toString(id++); 
      temp[1] = item; 
     cursor.addRow(temp); 
    }    
    String[] from = {"text"}; 
    int[] to = {R.id.name_entry}; 
    busStopCursorAdapter = new SimpleCursorAdapter(context, R.layout.listentry, cursor, from, to); 
+0

cảm ơn, nó làm việc. –

+1

Tôi chỉ cần thêm cột _id để tránh lỗi được giải thích [ở đây] (http://stackoverflow.com/questions/3360605/column-id-does-not-exist) –

+0

Có thực sự, tôi đã quên về '_id' – pawelzieba

11

Tôi đang gặp phải sự cố tương tự. Bạn có thể sử dụng SearchView.setSuggestionsAdapter() chỉ chấp nhận CursorAdapter. Mặt khác ... điểm là gì? Nếu bạn sử dụng tiêu chuẩn <android.support.v7.widget.SearchView /> thì nó chứa SearchAutoComplete mở rộng AppCompatAutoCompleteTextView bên trong. Các mã sau đây làm việc cho tôi:

List<String> items = Lists.newArrayList(new String[] {"aaaaa", "bbbbb", "ccccc", "ddddd"}); 
SearchView searchView = (SearchView) findViewById(R.id.autocomplete_searchview); 
SearchView.SearchAutoComplete searchSrcTextView = (SearchView.SearchAutoComplete) findViewById(android.support.v7.appcompat.R.id.search_src_text); 
searchSrcTextView.setThreshold(1); 
searchSrcTextView.setAdapter(new SuggestionAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, items)); 
searchSrcTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
    @Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     return; 
    } 
}); 

và mã Adaptor sau:

public class SuggestionAdapter<T> extends ArrayAdapter<T> { 

    private List<T> items; 
    private List<T> filteredItems; 
    private ArrayFilter mFilter; 

    public SuggestionAdapter(Context context, @LayoutRes int resource, @NonNull List<T> objects) { 
     super(context, resource, Lists.<T>newArrayList()); 
     this.items = objects; 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public T getItem(int position) { 
     return items.get(position); 
    } 

    @Override 
    public Filter getFilter() { 
     if (mFilter == null) { 
      mFilter = new ArrayFilter(); 
     } 
     return mFilter; 
    } 

    public int getCount() { 
     //todo: change to pattern-size 
     return items.size(); 
    } 

    private class ArrayFilter extends Filter { 
     @Override 
     protected FilterResults performFiltering(CharSequence prefix) { 
      FilterResults results = new FilterResults(); 

      //custom-filtering of results 
      results.values = items; 
      results.count = items.size(); 

      return results; 
     } 

     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      filteredItems = (List<T>) results.values; 
      if (results.count > 0) { 
       notifyDataSetChanged(); 
      } else { 
       notifyDataSetInvalidated(); 
      } 
     } 
    } 
} 
+0

Điều này trả về mọi thứ không có vấn đề gì bạn gõ – Mike6679

+0

Đây là giải pháp tốt nhất nếu bạn chưa có con trỏ thực (điền một con trỏ 'theo cách thủ công' là một bản vá xấu). Nó đang làm việc cho tôi bây giờ, nhưng tôi cần phải thay đổi một số mã ví dụ: - Tìm findViewById cho tìm kiếmTự động hoàn thành như searchView.findViewById - Ghi đè getItems và getCounts của bộ điều hợp, sử dụng filterItems thay vì các mục - Rõ ràng là bạn cần triển khai logic bộ lọc, như nhận xét '// lọc kết quả'. Cảm ơn rất nhiều về mã ví dụ! – AliMola

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