2010-12-31 26 views
6

Tôi có danh sách các quốc gia trong cơ sở dữ liệu. Tôi đã tạo một hoạt động quốc gia được chọn bao gồm hộp chỉnh sửa để lọc và danh sách hiển thị tên cờ và tên quốc gia.Đang cố lọc một ListView bằng runQueryOnBackgroundThread nhưng không có gì xảy ra - tôi đang thiếu gì?

Khi hoạt động bắt đầu danh sách hiển thị toàn bộ danh sách các quốc gia được sắp xếp theo thứ tự bảng chữ cái - hoạt động tốt. Khi khách hàng bắt đầu nhập vào hộp tìm kiếm, tôi muốn danh sách được lọc dựa trên cách nhập của họ. Truy vấn cơ sở dữ liệu của tôi trước đây đã làm việc trong một AutoCompleteView (tôi chỉ muốn chuyển sang một hộp văn bản và danh sách riêng biệt) vì vậy tôi biết truy vấn đầy đủ của mình và truy vấn ràng buộc của tôi đang hoạt động. Những gì tôi đã làm là thêm một TextWatcher vào EditText xem và mỗi khi văn bản được thay đổi tôi gọi SimpleCursorAdapter runQueryOnBackgroundThread của danh sách với các hộp văn bản chỉnh sửa như là ràng buộc. Vấn đề là danh sách không bao giờ được cập nhật. Tôi đã thiết lập các điểm ngắt trong trình gỡ lỗi và trình soạn thảo TextWatcher thực hiện lệnh gọi runQueryOnBackgroundThread và FilterQueryProvider của tôi được gọi với ràng buộc dự kiến. Truy vấn cơ sở dữ liệu hoạt động tốt và con trỏ được trả về.

Các bộ chuyển đổi con trỏ có một bộ cung cấp dịch vụ truy vấn lọc (và một chất kết dính view để hiển thị các cờ):

SimpleCursorAdapter adapter = new SimpleCursorAdapter (this, 
      R.layout.country_list_row, countryCursor, from, to); 
    adapter.setFilterQueryProvider (new CountryFilterProvider()); 
    adapter.setViewBinder (new FlagViewBinder()); 

Các FitlerQueryProvider:

private final class CountryFilterProvider implements FilterQueryProvider { 

    @Override 
    public Cursor runQuery (CharSequence constraint) { 
     Cursor countryCursor = myDbHelper.getCountryList (constraint); 
     startManagingCursor (countryCursor); 
     return countryCursor; 
    } 
} 

Và EditText có TextWatcher:

myCountrySearchText = (EditText)findViewById (R.id.entry); 
    myCountrySearchText.setHint (R.string.country_hint); 
    myCountrySearchText.addTextChangedListener (new TextWatcher() { 
     @Override 
     public void afterTextChanged (Editable s) { 
      SimpleCursorAdapter filterAdapter = (SimpleCursorAdapter)myCountryList.getAdapter(); 
      filterAdapter.runQueryOnBackgroundThread (s.toString()); 
     } 


     @Override 
     public void onTextChanged (CharSequence s, int start, int before, int count) { 
      // no work to do 
     } 


     @Override 
     public void beforeTextChanged (CharSequence s, int start, int count, int after) { 
      // no work to do 
     } 
    }); 

Truy vấn cho cơ sở dữ liệu trông giống như sau:

public Cursor getCountryList (CharSequence constraint) { 
    if (constraint == null || constraint.length() == 0) { 
     // Return the full list of countries 
     return myDataBase.query (DATABASE_COUNTRY_TABLE, 
       new String[] { KEY_ROWID, KEY_COUNTRYNAME, KEY_COUNTRYCODE }, null, null, null, 
       null, KEY_COUNTRYNAME); 
    } else { 
     // Return a list of countries who's name contains the passed in constraint 
     return myDataBase.query (DATABASE_COUNTRY_TABLE, 
       new String[] { KEY_ROWID, KEY_COUNTRYNAME, KEY_COUNTRYCODE }, 
       "Country like '%" + constraint.toString() + "%'", null, null, null, 
       "CASE WHEN Country like '" + constraint.toString() + 
       "%' THEN 0 ELSE 1 END, Country"); 
    } 
} 

Dường như có liên kết bị thiếu ở đâu đó. Bất kỳ trợ giúp sẽ được đánh giá cao.

Cảm ơn,

Ian

+0

Tại sao bạn muốn sử dụng TextWatcher w/EditText thay vì một AutoCompleteTextView? –

+0

Điều gì xảy ra nếu bạn muốn đưa ra một tùy chọn để cho phép người dùng cuộn qua một ListView cũng như lọc ListView. Theo hiểu biết của tôi, AutoCompleteTextView sẽ không cho phép bạn có một listView riêng biệt. – rohitmishra

Trả lời

3

Nó có vẻ như bạn đang làm rất nhiều công việc kiếm cái gì đó đã được xây dựng vào Android. Hãy xem Hộp thoại tìm kiếm trên Android tại http://developer.android.com/guide/topics/search/search-dialog.html và nó sẽ rất dễ dàng cho bạn.

+0

Tuyệt vời - vấn đề ban đầu của tôi vẫn là một chút bí ẩn nhưng đề xuất của bạn về việc sử dụng cơ sở tìm kiếm được xây dựng thực sự là một cách đúng đắn để đi. Tôi đã thêm phần triển khai vào ứng dụng của mình và nó hoạt động rất tốt. Bây giờ tôi đang xem xét các nhà cung cấp nội dung để tôi có thể đưa ra các đề xuất trong quá trình tìm kiếm và tích hợp vào hệ thống tốt hơn nữa. Cảm ơn! –

+0

Vui vì tôi có thể giúp! –

15

Tôi thấy rằng bạn đã xoay sở để giải quyết vấn đề của mình theo một cách khác, nhưng tôi nghĩ tôi nên thêm câu trả lời cho những người khác vấp phải câu hỏi này.

runQueryOnBackgroundThread() chỉ chịu trách nhiệm về việc chạy truy vấn cho một ràng buộc và trả về Con trỏ. Để có thể lọc các bộ chuyển đổi dựa trên con trỏ bạn cần phải làm điều gì đó như

filterAdapter.getFilter().filter(s.toString()); 

Một CursorAdapter luôn thực hiện lọc theo mặc định, và bất cứ điều gì mà thực hiện lọc có thể được lọc bằng

getFilter().filter(constraint)

Cách mà các CursorAdapters được xây dựng trong bộ lọc hoạt động là nếu bạn ghi đè lên runQueryOnBackgroundThread() hoặc nếu bạn sử dụng setFilterQueryProvider() thì nó chạy mã đó trong một chuỗi nền, lấy một con trỏ mới và đặt nó làm con trỏ của CursorAdapter.

+0

Cảm ơn thông tin đó tôi đánh giá cao nó và tôi chắc chắn tôi sẽ sử dụng nó tại một số điểm. –

+1

Đây phải là câu trả lời được chấp nhận là imho. – alaeri

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