AutoCompleteTextView with CursorLoader and SimpleCursorAdapter

I am trying to populate a list of sentences with db data. However, I get StaleDataException s. It is thrown out rather randomly, but always when I entered a character in a text box.

Here is my code:

CursorLoader extending the Cristian class SimpleCursorLoader

 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 callbacks:

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

And finally, when I installed 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); } 
+4
source share
1 answer

After some research, it seems that the SimpleCursorAdapter inherits from the ResourceCursorAdapter , which inherits from the CursorAdapter . CursorAdapter uses a CursorFilter to filter, and this class calls changeCursor() in its publishResults() . changeCursor closes the old cursor ... So why my cursors were closed automatically.

I reset the bootloaders and changed the implementation to the code below, and it works very hard:

 mAdapter = 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)); } }); 
+6
source

Source: https://habr.com/ru/post/1490508/


All Articles