Android 使用 AutoCompleteTextView 搭配 SQLite 取得曾經輸入的資料

為了讓輸入資料時更方便,試著使用了 AutoCompleteTextView 想讓 App 自動顯示以前輸入過的資料。

首先需要設定 AutoCompleteTextView 的 Adapter,一般的範例都使用 SimpleCursorAdapter。

Cursor cursor = dbHelper.getReadableDatabase()
.query(TABLE_EXPENSE, null, null, null, null, null, null);
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
cursor,
new String[]{COLUMN_MAIN_NAME},
new int[]{android.R.id.text1},
0);
view raw Activity2.java hosted with ❤ by GitHub
AutoCompleteTextView textName = findViewById(R.id.text_name);
textName.setAdapter(adapter);
view raw Activity1.java hosted with ❤ by GitHub
但是我們可以發現到,它會列出所有該欄位的內容,這樣子使用者先輸入的文字就沒有意義了。


原本想直接在 Cursor 設定 query 的條件,但沒想到竟然無效!不得已只好另尋它法,於是就在 SimpleCursorAdapter 找到了 setFilterQueryProvider。

adapter.setFilterQueryProvider(new FilterQueryProvider() {
@Override
public Cursor runQuery(CharSequence constraint) {
Cursor cursor = null;
if (constraint != null) {
// Cause by the design of CursorAdapter, query must contain column "_id".
cursor = dbHelper.getReadableDatabase().rawQuery(
"SELECT " + COLUMN_MAIN_ID + ", " + COLUMN_MAIN_NAME +
" FROM " + TABLE_EXPENSE +
" WHERE " + COLUMN_MAIN_NAME + " LIKE '%" + name +
"%' GROUP BY " + COLUMN_MAIN_NAME, null);
}
return cursor;
}
});
view raw Activity3.java hosted with ❤ by GitHub
這邊有兩個重點要注意:
第一是根據 SimpleCursorAdapter 的父類別 CursorAdapter 的設計,資料的欄位(Column)必須包含「_id」這個名字的欄位,所以在 SQL 指令的 SELECT 後必須加入「_id」。
第二個則是使用者體驗的考量,不要讓結果出現重複的內容;這可以在 SQL 指令中使用「GROUP BY」來實現。
下面左圖為沒有 GROUP BY,右圖則有使用 GROUP BY:


到這邊看似已經完成了吧?但其實還有最後一個坑!


點選自動完成的內容後,得到的不是想像中的文字,而是類似物件位址的一長串字!
原因是前面 setFilterQueryProvider 得到的是 Cursor,而我們必須再從中取出需要的資料。
這邊使用的是 setCursorToStringConverter。

adapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
@Override
public CharSequence convertToString(Cursor cursor) {
return cursor.getString(1);
}
});
view raw Activity4.java hosted with ❤ by GitHub
做到這一步,終於完成了

留言

這個網誌中的熱門文章

Android 藍牙連接通訊實作心得

在 Android 上自訂 Zxing 掃描框樣式與大小位置