如何在简单游标适配器上实现搜索?

How to implement search on simple cursor adapter?

在我的申请中。我想实现放置在操作栏中的搜索视图。我正在使用简单的游标适配器。简单光标适配器中有一个图像视图和一个文本视图。我想实现基于textview内容的搜索。但是我得到了空指针异常。

我的简单游标适配器:

 SimpleCursorAdapter c_adapter = new SimpleCursorAdapter(getActivity(), R.layout.contact_item, mCursor,
        new String[]{ContactsContract.Contacts.DISPLAY_NAME
                , ContactsContract.Contacts.PHOTO_THUMBNAIL_URI, ContactsContract.Contacts._ID},

        new int[]{R.id.username1, R.id.ivuserpicicon1});

我在 :

中遇到错误
c_adapter.getFilter().filter(newText);

为此,我们必须使用 setfilterqueryprovider() 并使用所需的查询来选择特定列。

public class MainActivity extends ActionBarActivity {

    ListView listview;
    SimpleCursorAdapter c_adapter;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Cursor mCursor = getContacts();
        c_adapter = new SimpleCursorAdapter(MainActivity.this, R.layout.contact_item, mCursor,
        new String[]{ContactsContract.Contacts.DISPLAY_NAME
            , ContactsContract.Contacts.PHOTO_THUMBNAIL_URI, ContactsContract.Contacts._ID},
        new int[]{R.id.username1, R.id.ivuserpicicon1});

        listview = (ListView) findViewById(R.id.listview);
        listview.setAdapter(c_adapter);

        c_adapter.setFilterQueryProvider(new FilterQueryProvider() {
            public Cursor runQuery(CharSequence constraint) {
                return getCursor(constraint.toString());
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu){
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);
        SearchManager SManager =  (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        MenuItem searchMenuItem = menu.findItem(R.id.action_search);
        android.support.v7.widget.SearchView searchViewAction = (android.support.v7.widget.SearchView) MenuItemCompat.getActionView(searchMenuItem);
        searchViewAction.setSearchableInfo(SManager.getSearchableInfo(getComponentName()));
        searchViewAction.setIconifiedByDefault(true);
////////////////////////////////////////////////////////////////////////////////////
        android.support.v7.widget.SearchView.OnQueryTextListener textChangeListener = new android.support.v7.widget.SearchView.OnQueryTextListener()
        {
            @Override
            public boolean onQueryTextChange(String newText)
            {
                c_adapter.getFilter().filter(newText);
                System.out.println("on text chnge text: " + newText);
                return true;
            }
            @Override
            public boolean onQueryTextSubmit(String query)
            {
                c_adapter.getFilter().filter(query);
                System.out.println("on query submit: "+query);
                return true;
            }
        };
        searchViewAction.setOnQueryTextListener(textChangeListener);
///////////////////////////////////////////////////////////////////////////////////////
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_search:
            //openSearch();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    private Cursor getContacts() {
        // Run query
        Uri uri = ContactsContract.Contacts.CONTENT_URI;
        String[] projection = new String[]{ContactsContract.Contacts.DISPLAY_NAME,
            ContactsContract.Contacts.PHOTO_THUMBNAIL_URI, ContactsContract.Contacts._ID};
        String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP+" = "+
             1  +" AND "+ ContactsContract.Contacts.HAS_PHONE_NUMBER +" = "+ 1;
        String[] selectionArgs = null;
        String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
            + " COLLATE LOCALIZED ASC";
        return getContentResolver().query(uri, projection, selection, selectionArgs,
            sortOrder);
    }

    private Cursor getCursor(String str) {
        Cursor mCursor = null;
        if (str == null  ||  str.length () == 0)  {
            mCursor = getContacts();
        }
        else {
            Uri uri = ContactsContract.Contacts.CONTENT_URI;
            String[] projection = new String[]{ContactsContract.Contacts.DISPLAY_NAME,
            ContactsContract.Contacts.PHOTO_THUMBNAIL_URI, ContactsContract.Contacts._ID};
            String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = " +
            1 + " AND " + ContactsContract.Contacts.HAS_PHONE_NUMBER + " = " + 1 + " AND " + ContactsContract.Contacts.DISPLAY_NAME + " like '" + str + "%'";
        String[] selectionArgs = null;
        String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
            + " COLLATE LOCALIZED ASC";
        mCursor = getContentResolver().query(uri, projection, selection, selectionArgs,
            sortOrder);
        }

        if (mCursor != null) {
            mCursor.moveToFirst();
        }

        return mCursor;
    }
}

如果您使用 CursorLoader 从数据库中获取数据,并且您的 class 实现了 LoaderManager.LoaderCallbacks<Cursor>,请参阅此以了解如何 filter/search 数据:

http://android-er.blogspot.co.uk/2013/02/query-contacts-database-using-loader.html