I am having an issue implementing CursorAdapter on an AutoCompleteTextView.
ZipCode : _ (<--EditText)
City : ____ (<-- AutoCompleteTextView)
Basically, I want to help the user suggesting available cities for the Zip Code entered.
My issue is that the suggestions are not shown (Cursor does not launch query i guess). What i don't understand is why it's working in some cases and not in other ones. I attach the faulty case below.
My Cursor Adapter :
public class SearchCursorAdapter extends CursorAdapter {
private DataBaseHelper mDbHelper;
private String codePostal;
public SearchCursorAdapter(DataBaseHelper dbHelper, Context context,
String codePostal) {
// Call the CursorAdapter constructor with a null Cursor.
super(context, null, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
mDbHelper = dbHelper;
this.codePostal = codePostal;
}
@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (getFilterQueryProvider() != null) {
return getFilterQueryProvider().runQuery(constraint);
}
Cursor cursor = mDbHelper.getStationCursor(constraint.toString(),
codePostal);
return cursor;
}
@Override
public String convertToString(Cursor cursor) {
return cursor.getString(1); //second column in select
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
((TextView) view).setText(cursor.getString(1)); //second column in select
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.spinner_layout, null);
return view;
}
}
The select method from db adapter :
public Cursor getStationCursor(String args, String arg2) {
StringBuffer sqlQuery = new StringBuffer("");
Cursor result = null;
sqlQuery.append(" SELECT min(_id) as _id, ");
sqlQuery.append(CITIES.CITY);
sqlQuery.append(" FROM ");
sqlQuery.append(CITIES.TABLE_NAME);
sqlQuery.append(" WHERE ");
sqlQuery.append(CITIES.CITY);
sqlQuery.append(" LIKE '");
sqlQuery.append(args);
sqlQuery.append("%' ");
sqlQuery.append("AND ");
sqlQuery.append(CITIES.CODE_POSTAL);
sqlQuery.append(" LIKE '");
sqlQuery.append(arg2);
sqlQuery.append("%' ");
sqlQuery.append(" GROUP BY ");
sqlQuery.append(CITIES.CITY);
sqlQuery.append(" ORDER BY ");
sqlQuery.append(CITIES.CITY);
sqlQuery.append(" LIMIT 10 ");
if (myDataBase != null) {
result = myDataBase.rawQuery(sqlQuery.toString(), null);
}
if (result != null) {
result.moveToFirst();
}
return result;
}
The code in my activity :
EditText etCodPost;
AutoCompleteTextView acCity;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout....);
etCodPost = (EditText) ...;
acCom = (AutoCompleteTextView) ...;
setComAdapter(activity);
etCodPost.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
setComAdapter(activity);
}
});
}
private void setComAdapter(Activity activity) {
SearchCursorAdapter adapt = new SearchCursorAdapter(myDbHelper, activity,
etCodPost.getText().toString());
acCity.setAdapter(adapt);
acCity.setThreshold(3);
}
Thanks for your replies and sorry for the long post. Any hint would be very appreciated.
You don't mention at least one of the cases where the filtering fails so the lines below come more from guessing:
I think you setup the filtering wrong. There is no need to set the adapter each time when the user enters a code, a simpler solution would be to have a field in the activity class, an int
(or String
from your code) which would be used as part of the query.
@Override
public void afterTextChanged(Editable s) {
mCode = s.toString;
}
Next, filtering at the adapter level could be improved like this:
@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (constraint == null || constraint.toString.equals("")) {
// this is the contract of this method and should be respected
return mDbHelper.getAllCityRecords(); // get all records
}
return mDbHelper.getStationCursor(constraint.toString(),
mCode); // mCode is the field that is updated in the activity class(you should take in consideration that the user could use directly the AutoCompleteTextView, so mCode could be not set at this level)
return cursor;
}
Last, you probably did this, but do make sure that you get what you expect when querying(directly) the database. As the filtering works for some cases it may be something to look after.