我有一个自定义光标适配器,我想将光标的每一“行”传递回应用程序(通过一个正在工作的注册回调)。
我知道我可以从光标读取每个字段并手动执行,但我只想将光标的“冻结克隆”传回。(阅读适配器中的字段需要我制作这个类的几个专门版本。)
理想情况下,我想传回与 Cursor 具有相同接口但无法遍历结果集的东西。
查询返回的行数少于 20,因此空间不是问题。
我猜你有一个有 20 行的游标,现在你想用一个只包含一行的游标调用一个方法 20 次。您可以这样做:
Cursor c = ...;// contains many rows
if(c.moveToFirst()){
String[] columns = c.getColumnNames();
while(!c.isAfterLast()){
MatrixCursor newCursor = new MatrixCursor(columns , 1);
MatrixCursor.RowBuilder b = newCursor.newRow();
for(String col: columns){
// in case all columns are of string type. But if they are
// different then see my comment below
b.add(c.getString(c.getColumnIndex(col)));
}
// invoke your listener here with newCursor
}
}
如果列的数据类型不是字符串怎么办?
对于 API>=11:只需getType()
在for
循环中调用方法并使用switch
语句调用适当的 get 方法。
对于 API<11:运行与此类似的另一个查询PRAGMA table_info(my_table_name)
,然后只需填写一个Map
列名并键入并在 for 循环中使用它。这是阅读此光标的方法https://stackoverflow.com/a/9354401/1112882
假设您有一个名为 data 的游标,并且游标具有列“title”和“author”,并且这两列都有字符串值。下面的代码显示了如何将名为 data 的游标复制到名为 matrixCursor 的游标中。
String[] PROJECTION = new String[]{"title","author"};
MatrixCursor matrixCursor = new MatrixCursor(PROJECTION);
int i = data.getColumnCount();
if (data.moveToFirst()) {
do {
Object[] currRow = new Object[i];
currRow[0] = data.getString(0);
currRow[1] = data.getString(1);
matrixCursor.addRow(currRow);
} while (data.moveToNext());
}
根据Anand 的回答,这应该可以工作,而无需指定列名/投影:
public static Cursor cloneCursor(Cursor oldCursor) {
if (oldCursor == null) {
return null;
}
else {
/**
* Remember the cursor position
*/
int originalCursorPosition = oldCursor.getPosition();
String[] projection = oldCursor.getColumnNames();
MatrixCursor newCursor = new MatrixCursor(projection);
int numColumns = oldCursor.getColumnCount();
while (oldCursor.moveToNext()) {
/**
* Create the new row object
*/
Object[] newRow = new Object[numColumns];
/**
* Populate each column in the new row
*/
for (int columnIndex = 0; columnIndex < numColumns; columnIndex++) {
/**
* Detect the field type
*/
int fieldType = oldCursor.getType(columnIndex);
/**
* Use the field type to populate the row correctly
*/
if (fieldType == Cursor.FIELD_TYPE_BLOB) {
newRow[columnIndex] = oldCursor.getBlob(columnIndex);
}
else if (fieldType == Cursor.FIELD_TYPE_FLOAT) {
newRow[columnIndex] = oldCursor.getDouble(columnIndex);
}
else if (fieldType == Cursor.FIELD_TYPE_INTEGER) {
newRow[columnIndex] = oldCursor.getLong(columnIndex);
}
else if (fieldType == Cursor.FIELD_TYPE_STRING) {
newRow[columnIndex] = oldCursor.getString(columnIndex);
}
else if (fieldType == Cursor.FIELD_TYPE_NULL) {
newRow[columnIndex] = null;
}
else {
throw new RuntimeException("Unknown fieldType (" + fieldType + ") for column" + columnIndex);
}
}
/**
* Add the new row to the new cursor
*/
newCursor.addRow(newRow);
}
/**
* Move both cursors to the position that oldCursor was in before this method was called
*/
oldCursor.moveToPosition(originalCursorPosition);
newCursor.moveToPosition(originalCursorPosition);
/**
* Return the cloned cursor
*/
return newCursor;
}
}
更新
getInt(...)
更改为getLong(...)
.
getFloat(...)
变成getDouble(...)