使用CursorLoader和SimpleCursorAdapter的AutoCompleteTextView

时间:2013-07-09 15:03:48

标签: android android-sqlite simplecursoradapter android-cursoradapter android-cursor

我尝试使用db表的数据填充建议列表。但是我得到StaleDataException s。它会随机抛出,但总是在我在textview中输入一个字符时。

这是我的代码:

CursorLoader扩展CristianSimpleCursorLoader

public class TagCursorLoader extends SimpleCursorLoader {

    private String mSelection;
    private TagDbLoader mDbLoader;

    public TagCursorLoader(Context context, TagDbLoader dBLoader, String selection) {
        super(context);
        this.mDbLoader = dBLoader;
        this.mSelection = selection;
    }

    @Override
    public Cursor loadInBackground() {
        return mDbLoader.fetchContainingString(mSelection);
    }

}

Loader回调:

public class TagCursorLoaderCallback implements LoaderCallbacks<Cursor>, CursorToStringConverter {

    private Context mContext;
    private TagDbLoader mdDbLoader;
    private SimpleCursorAdapter mAdapter;
    private String mSelection;

    public TagCursorLoaderCallback(Context context, TagDbLoader dBLoader, SimpleCursorAdapter adapter) {
        this.mContext = context;
        this.mdDbLoader = dBLoader;
        mAdapter = adapter;
        mSelection = "";
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new TagCursorLoader(mContext, mdDbLoader, mSelection);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

        if (!data.isClosed()) {
            mAdapter.swapCursor(data);
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mAdapter.swapCursor(null);
    }

    public void setSelection(String mSelection) {
        this.mSelection = mSelection;
    }

    @Override
    public CharSequence convertToString(Cursor cursor) {
        return cursor.getString(cursor.getColumnIndexOrThrow(DbConstants.Tags.KEY_TAG));
    }

}

最后,当我设置AutoCompleteTextView

private void initializeAutoComplete() {

        mTagDbLoader = new TagDbLoader(getActivity());
        mTagDbLoader.open();

        mTagInput = (AutoCompleteTextView) mLayout.findViewById(R.id.autoComplete);

        mTagInput.addTextChangedListener(new TextWatcherAdapter() {

            @Override
            public void afterTextChanged(Editable s) {
                mLoaderCallback.setSelection(s.toString());
                getLoaderManager().restartLoader(0, null, mLoaderCallback);
            }
        });

        mAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_1,
                null, new String[] { DbConstants.Tags.KEY_TAG }, new int[] { android.R.id.text1 },
                0);

        mLoaderCallback = new TagCursorLoaderCallback(getActivity(), mTagDbLoader, mAdapter);
        mAdapter.setCursorToStringConverter(mLoaderCallback);
        mTagInput.setAdapter(mAdapter);
        getLoaderManager().initLoader(0, null, mLoaderCallback);
    }

1 个答案:

答案 0 :(得分:6)

经过一些调查后,似乎SimpleCursorAdapter继承自ResourceCursorAdapterCursorAdapter继承自CursorAdapterCursorFilter使用changeCursor()进行过滤,此类会在其publishResults()中调用changeCursormAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, mTagDbLoader.fetchAll(), new String[] { DbConstants.Tags.KEY_TAG }, new int[] { android.R.id.text1 }, 0); mAdapter.setFilterQueryProvider(new FilterQueryProvider() { @Override public Cursor runQuery(CharSequence constraint) { if (constraint == null || constraint.equals("")) return mAdapter.getCursor(); return mTagDbLoader.fetchContainingString(constraint.toString()); } }); mAdapter.setCursorToStringConverter(new CursorToStringConverter() { @Override public CharSequence convertToString(Cursor c) { return c.getString(c.getColumnIndexOrThrow(DbConstants.Tags.KEY_TAG)); } }); 关闭旧光标......这就是我的光标自动关闭的原因。

我删除了加载器,并将实现更改为下面的代码,并且它非常有效:

{{1}}