如何改进自动完成文本小部件中的搜索

How do I improve Searching in an AutoComplete text widget

我有两个 AutoCompleteTextView,其中填充了来自 sqlite 数据库的数据。我从 ERP 服务器中提取信息并将其本地存储在 sqlite 数据库中,并像这样填充文本视图:

equipment = (AutoCompleteTextView) findViewById(R.id.equipmentAutoCompleteTextView);
    if(equipment.getText().toString().length() == 0){
        equipment.setError("Equipment is required");
    }
    FieldInstallationDB sqlitedb1 = new FieldInstallationDB(this);
    sqlitedb1.openForRead();

    String[] items = sqlitedb.getAllItemNames();

    for(int i = 0; i < items.length; i++)
    {
        Log.i(this.toString(), items[i]);
    }

    ArrayAdapter<String> adapter1 = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, items);
    equipment.setAdapter(adapter1);
    equipment.setThreshold(1);

这里:

customerName = (AutoCompleteTextView) findViewById(R.id.customerNameAutoCompleteTextView);
    if(customerName.getText().toString().length() == 0){
        customerName.setError("Customer Name is required");
    }
    FieldInstallationDB sqlitedb = new FieldInstallationDB(this);
    sqlitedb.openForRead();

    String[] accounts = sqlitedb.getAllCustNames();

    for(int i = 0; i < accounts.length; i++)
    {
        Log.i(this.toString(), accounts[i]);
    }

    ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, accounts);
    customerName.setAdapter(adapter);
    customerName.setThreshold(1);

假设我有这些:

然后我开始输入 "spo",我想查看列出的所有三个项目以进行选择。相反,我只得到 "Spoonful" 出现。我如何让它识别并显示所有具有字母 "spo"?

的实例(项目)

更新:

在对我的问题发表第一条评论后,我阅读了更多文章并将我的代码更新为如下所示:

equipment = (AutoCompleteTextView) findViewById(R.id.equipmentAutoCompleteTextView);
    if(equipment.getText().toString().length() == 0){
        equipment.setError("Equipment is required");
    }
    FieldInstallationDB sqlitedb1 = new FieldInstallationDB(this);
    sqlitedb1.openForRead();

    String[] items = sqlitedb1.getAllItemNames();

    for(int i = 0; i < items.length; i++)
    {
        Log.i(this.toString(), items[i]);
    }

    equipment.setThreshold(1);


    SimpleCursorAdapter itemNameAdapter = new SimpleCursorAdapter(
            this, android.R.layout.simple_dropdown_item_1line, null, items, toView, 0);



    itemNameAdapter.setFilterQueryProvider(new FilterQueryProvider() {

        public Cursor runQuery(CharSequence constraint) {
            return suggestItemCompletions(constraint);
        }
    });

itemNameAdapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
        public CharSequence convertToString(Cursor cur) {
            int index = cur.getColumnIndex(FieldInstallationDB.ITEM_NAME);
            return cur.getString(index);
        }});
    equipment.setAdapter(itemNameAdapter);

这里是activityclass中写的suggestitemcompletions方法:

public Cursor suggestItemCompletions(CharSequence str) {

    return getContentResolver().query(null, new String[] {FieldInstallationDB.ITEM_NAME}, "(" + FieldInstallationDB.ITEM_NAME + " LIKE ? ", new String[] {"%" + str + "%"}, null);

}

这建议使用 getContentResolver(),这对我来说没有意义,因为我访问的是我的应用程序的数据库,而不是另一个应用程序的数据库。结果它不起作用,因为我将 URI 参数设置为空,因为我的数据库 table 没有 URI。但是,如果我决定不使用 getContentResolver() 并直接查询 FieldInstallationDB,我会在 .query() 处收到错误消息,说无法解析方法。

更新二:

我按照建议使用了 rawQuery() 并且有效:

public Cursor suggestItemCompletions(CharSequence str) {
    fieldInstDatabase = openForRead();
    String sql = "Select "+ ITEM_NAME+ " FROM "+ TABLE_EQUIPMENT+ " WHERE "+ ITEM_NAME + " LIKE ?";
    String[]  selectArgs = new String[]{ "%" + str + "%"};

    return fieldInstDatabase.rawQuery(sql,selectArgs);

}

这个方法在我的数据库 class 中,我在主 activity 中调用它:

itemNameAdapter.setFilterQueryProvider(new FilterQueryProvider() {

        public Cursor runQuery(CharSequence constraint) {
            return sqlitedb1.suggestItemCompletions(constraint);
        }
    });

除了我在这里收到 IllegalArgumentException:

01-10 13:07:08.792 5361-5361/com.example.sweetiean.stlfieldinstallation1 E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.sweetiean.stlfieldinstallation1, PID: 5361 java.lang.IllegalArgumentException: column 'Bag(TypeC) : 5900016009' does not exist

这是有道理的,因为“Bag(TypeC): 5900016009" 不是列,它是数据库中 ITEM NAME 列中的第一项。

我不知道为什么它读取第一项作为列名。我已尝试调试,但无法进入

public Cursor runQuery(CharSequence constraint) {
        return sqlitedb1.suggestItemCompletions(constraint);
    }

正如评论中所建议的,由于我的 SimpleCursorAdapter 中的 from 参数,此处发生了 IllegalArgumentException。 SimpleCursorAdapter 的 fromto 参数需要分别填充 table 和文本视图的列名。

在我的例子中,我使用从数据库中获取的项目的字符串数组填充 from 参数:

String[] items = sqlitedb1.getAllItemNames();

for(int i = 0; i < items.length; i++)
{
    Log.i(this.toString(), items[i]);
}

equipment.setThreshold(1);


SimpleCursorAdapter itemNameAdapter = new SimpleCursorAdapter(
        this, android.R.layout.simple_dropdown_item_1line, null, items, toView, 0);

更正为:

SimpleCursorAdapter itemNameAdapter = new SimpleCursorAdapter(
        this, android.R.layout.simple_dropdown_item_1line, null, fromCol, toView, 0);

fromCol 定义为 final static String[] fromCol = new String[] { FieldInstallationDB.ITEM_NAME }; 修复了它。