Android - 当用户选择第三个建议时,在AutoCompleteTextView中使用SimpleCursorAdapter会产生CursorIndexOutofBoundsException

时间:2014-11-27 06:05:31

标签: android simplecursoradapter android-cursoradapter matrixcursor

对于满口的标题,我不得不将其删除,因为我超过了150个字符的限制。

我有一个AutoCompleteTextView(ACTV)并且我正在使用SimpleCursorAdapter,因为普通的ACTV只在每个子字符串的开头搜索用户输入(子字符串由空格分隔)而不在那些子字符串中子。例如,拥有包含AdiposeBad Wolf的列表并搜索ad的列表只会显示Adipose而不显示Bad Wolf。我已经制作了如下所示的适配器:

//create ACTV Here
AutoCompleteTextView search = (AutoCompleteTextView) findViewById(R.id.actvCatalogueSearch);
search.setThreshold(1);

String[] from = { "name" };
int[] to = { android.R.id.text1 };

SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, 
        android.R.layout.simple_dropdown_item_1line, null, from, to, 0);

cursorAdapter.setStringConversionColumn(1);

FilterQueryProvider provider = new FilterQueryProvider(){
    @Override
    public Cursor runQuery(CharSequence constraint) {
        // TODO Auto-generated method stub
        String constrain = (String) constraint;
        constrain = constrain.toUpperCase();
        Log.d("hi", "runQuery constraint: " + constraint);
        if (constraint == null) {
            return null;
        }
        String[] columnNames = { Columns._ID, "name" };
        MatrixCursor c = new MatrixCursor(columnNames);
        try {
            for (int i = 0; i < pdflist.length; i++) {
                if(pdflist[i].contains(constrain)){
                    Log.d("Hello","Match! pdflist item = " + pdflist[i]);
                    c.newRow().add(i).add(pdflist[i]);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return c;
    }
};

cursorAdapter.setFilterQueryProvider(provider);
search.setAdapter(cursorAdapter);

此代码使我能够显示包含用户输入的子字符串的其他列表项。

现在,我正在努力使OnItemClickListener功能正常运行。以下是我到目前为止的情况:

search.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
        MatrixCursor matrix = (MatrixCursor)parent.getItemAtPosition(position);

        Log.d("hello", "matrix values is = " + matrix);

        String selection = matrix.getString(position);  
        Log.d("hallo","selection = " + selection);
        Log.d("hello","item id at position = " + parent.getItemIdAtPosition(position));

        int pos = (int) parent.getItemIdAtPosition(position);
        Log.d("sup", "position is = " + pos);
        String path = imagelist[pos].getAbsolutePath();
        openPdfIntent(path);
    }
});

在这里,我试图将MatrixCursor元素放在给定位置。它工作正常,用户选择前2个建议。但是,当用户点击第3个建议时,应用程序会抛出CursorIndexOutOfBoundsException Requested Column: 2, # of columns: 2点击logCat行指向代码String selection = matrix.getString(position);

我认为执行matrix.getString(position)会导致错误,因为getString将所请求列的值作为String返回,并且因为只有2列,所以在ACTV中选择一个位置(位置如图所示)对于用户而言,不是列表中所述项目的位置大于2会导致代码搞砸。

我的问题是,如果我使用SimpleCursorAdapter,是否有更好的方法来获取所选项目的字符串值?我已经在android开发站点查看了Matrix Cursor的文档,但我找不到根据位置获取行/元素的方法。

非常感谢任何帮助。

编辑:

使用matrix.moveToFirst();这样做也无济于事:

search.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
        MatrixCursor matrix = (MatrixCursor)parent.getItemAtPosition(position);
        if(matrix != null) {
            if(matrix.getCount() > 0) {
                matrix.moveToFirst();
                String selection = matrix.getString(position);  

                int pos = (int) parent.getItemIdAtPosition(position);
                String path = imagelist[pos].getAbsolutePath();
                openPdfIntent(path);
            }    
        }
    }
});

我还有例外:

android.database.CursorIndexOutOfBoundsException: Requested column: 4, # of columns: 2

请求的列4是所选ACTV建议的位置,索引为零。

2 个答案:

答案 0 :(得分:0)

尝试这样

MatrixCursor matrix = .............

Log.d("hello", "matrix values is = " + matrix);

/***** Check here Cursor is NOT NULL *****/
if(matrix != null) {
    if(matrix.getCount() > 0) {
        matrix.moveToFirst();
        /***
        Your Stuff will be here....
        **/
    }    
}

答案 1 :(得分:0)

使用不同的方法使其工作。我得到视图并将其转换为TextView。从那里,我得到String输入。然后我使用此字符串并查找其在原始列表中的位置。请注意,我的列表是一个数组,而不是一个ArrayList,这就是我必须遍历所有项目的原因。

search.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        TextView tv = (TextView) view;
        String userSelection = tv.getText().toString();
        Log.d("hello", "selection is = " + userSelection);

        int pos = -1;

        for (int i = 0; i < pdflist.length; i++) {
            if(pdflist[i].equalsIgnoreCase(userSelection)){
                pos = i;
            }
        }

        Log.d("hello","int position = " + pos);

        String path = imagelist[pos].getAbsolutePath();
        openPdfIntent(path);
    }
});