ok try this:
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
AutoCompleteTextView actv = new AutoCompleteTextView(this);
actv.setThreshold(1);
String[] from = {"name"};
int[] to = {android.R.id.text1};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_dropdown_item_1line, null, from, to) {
// required for Spanned data
@Override
public void bindView(View view, Context context, Cursor cursor) {
MyCursor c = (MyCursor) cursor;
TextView tv = (TextView) view;
tv.setText(c.getSpanned());
}
// required for Spanned data
@Override
public CharSequence convertToString(Cursor cursor) {
MyCursor c = (MyCursor) cursor;
return c.getSpanned();
}
};
FilterQueryProvider provider = new FilterQueryProvider() {
@Override
public Cursor runQuery(CharSequence constraint) {
if (constraint == null) {
return null;
}
MyCursor c = new MyCursor();
// fake web service responses
List<String> names = callFakeWebService(constraint);
int i = 0;
for (String name: names) {
SpannableStringBuilder ssb = new SpannableStringBuilder(name);
int start = name.indexOf(" ");
ForegroundColorSpan what = new ForegroundColorSpan(0xffff0000);
ssb.setSpan(what, start + 1, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
c.newRow().add(i++).add(name);
c.addSpanned(ssb);
}
return c;
}
// fake web service request
private List<String> callFakeWebService(CharSequence constraint) {
Log.d(TAG, "callFakeWebService for: " + constraint);
String[] namesArr = {
"Mark Smith",
"Monica Thompson",
"John White",
"Jane Brown"
};
String stringConstraint = constraint.toString().toLowerCase();
List<String> names = new ArrayList<String>();
for (int i = 0; i < namesArr.length; i++) {
String name = namesArr[i];
if (name.toLowerCase().startsWith(stringConstraint)) {
names.add(name);
}
}
return names;
}
};
adapter.setFilterQueryProvider(provider);
actv.setAdapter(adapter);
ll.addView(actv);
TextView tv = new TextView(this);
tv.setTextSize(32);
tv.setTextColor(0xffff0000);
tv.setText("type one of:\n mark,\n monica,\n john\n jane");
ll.addView(tv);
setContentView(ll);
where custom Cursor could look like this (it is minimalistic version supporting only one Spanned in a row):
static class MyCursor extends MatrixCursor {
private static final String[] NAMES = {BaseColumns._ID, "name"};
private ArrayList<Spanned> mSpannedList;
public MyCursor() {
super(NAMES);
mSpannedList = new ArrayList<Spanned>();
}
public void addSpanned(Spanned s) {
mSpannedList.add(s);
}
public Spanned getSpanned() {
return mSpannedList.get(mPos);
}
}
EDIT with no Spanned text:
AutoCompleteTextView actv = new AutoCompleteTextView(this);
actv.setThreshold(1);
final String[] from = {BaseColumns._ID, "name", "artist", "title"};
int[] to = {R.id.list_image, R.id.textView1, R.id.textView2, R.id.textView3};
final SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.list_row, null, from, to);
adapter.setStringConversionColumn(1);
ViewBinder viewBinder = new ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if (columnIndex == 0) {
ImageView iv = (ImageView) view;
Bitmap bitmap = cursor.getExtras().getParcelable("image");
if (bitmap != null) {
iv.setImageBitmap(bitmap);
}
return true;
}
return false;
}
};
adapter.setViewBinder(viewBinder);
FilterQueryProvider provider = new FilterQueryProvider() {
ExecutorService mPool = Executors.newCachedThreadPool();
Uri URI = Uri.parse("adapter://autocomplete");
public Cursor runQuery(CharSequence constraint) {
if (constraint == null) {
return null;
}
try {
return callWebService(constraint, from);
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
// here you make the web request
private Cursor callWebService(CharSequence constraint, String[] columnNames) throws JSONException {
Log.d("TAG", "callWebService for: " + constraint);
MatrixCursor cursor = new MyMatrixCursor(columnNames);
// TODO do real network request
// call web service here and keep the result in "jsonStr"
String jsonStr = "{\"ResultArray\":[{\"data\":{ \"sno\":\"sno1\", \"date\":\"2011-08-21 14:27:09\", \"user\":\"1\", \"link\":\"http://scm-l3.technorati.com/11/11/17/56749/google-docs-revision.jpg?t=20111117074048\", \"name\":\"Aa\" }},{\"data\":{ \"sno\":\"sno2\", \"date\":\"2011-08-21 14:28:09\", \"user\":\"2\", \"link\":\"http://kcclaveria.com/wp-content/uploads/2013/02/google-panda-penguin.jpg\", \"name\":\"Bb\" }}]}";
JSONObject json = new JSONObject(jsonStr);
JSONArray resultArray = json.getJSONArray("ResultArray");
int length = resultArray.length();
for (int i = 0; i < length; i++) {
JSONObject data = resultArray.getJSONObject(i).getJSONObject("data");
cursor.newRow().add(i)
.add(data.getString("name"))
.add(data.getString("user"))
.add(data.getString("sno"));
String link = data.getString("link");
// get cached Bundle based on "link" (use HashMap<String, Bundle>)
// or if new link initiate async request for getting the bitmap
// TODO implement HashMap caching
// new async request
Bundle extras = new Bundle();
try {
mPool.submit(new ImageRequest(link, extras));
} catch (MalformedURLException e) {
e.printStackTrace();
}
cursor.respond(extras);
}
cursor.setNotificationUri(getContentResolver(), URI);
return cursor;
}
class ImageRequest implements Runnable {
private URL mUrl;
private Bundle mExtra;
public ImageRequest(String link, Bundle extra) throws MalformedURLException {
mUrl = new URL(link);
mExtra = extra;
}
@Override
public void run() {
// TODO do real network request
// simulate network delay
Log.d(TAG, "getting " + mUrl);
try {
Thread.sleep(2000 + (long) (4000 * Math.random()));
} catch (InterruptedException e) {
e.printStackTrace();
}
Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
mExtra.putParcelable("image", b);
getContentResolver().notifyChange(URI, null);
Log.d(TAG, "run got a bitmap " + b.getWidth() + "x" + b.getHeight());
}
}
};
adapter.setFilterQueryProvider(provider);
actv.setAdapter(adapter);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
setContentView(actv, params);
and the custom MatrixCursor:
class MyMatrixCursor extends MatrixCursor {
List<Bundle> mBundles = new ArrayList<Bundle>();
public MyMatrixCursor(String[] columnNames) {
super(columnNames);
}
@Override
public Bundle respond(Bundle extras) {
mBundles.add(extras);
return extras;
}
@Override
public Bundle getExtras() {
return mBundles.get(mPos);
}
}