如何使用CursorLoader逐个显示单个数据库记录

时间:2012-01-03 03:22:03

标签: android android-loadermanager

我正在尝试为包含问题和相应答案的每条记录制作一个ContentProvider。还有一个Activity显示每个问题和答案的TextViews以及这些TextViews下面的“下一步”按钮。单击“下一步”按钮时,我希望显示下一个问题和答案。

我正在尝试使用CursorLoader和LoaderManager,因为CursorLoaders将数据保存在onStop()onStart()之间,我正在尝试了解CursorLoaders和{{1} }。

我发现的所有示例都使用LoaderManagers,但我不希望我的活动看起来像列表。我尝试使用setListAdapter()并使用SimpleCursorAdapter到我的bindView()布局来解决这个问题。不确定它会起作用。

如果我有一个普通的Cursor,我会使用main.xml,但对于moveToNext(),似乎我必须LoaderManager使用新的查询。我认为创建一个新查询会花费更多的时间,而不是简单地使用游标转到下一条记录。特别是因为我必须知道当前或下一个记录的位置。

所以我的问题是:我可以使用restartLoader()CursorLoader来浏览数据库,记录而不必为下一条记录创建新查询吗?或LoaderManagerCursorLoaders真的只适用于ListViews吗?

到目前为止,这是我的代码,我意识到它并不多,但我已阅读并重新阅读了Loaders和LoadManagers上的Android页面。

LoaderManagers

1 个答案:

答案 0 :(得分:0)

我明白我的问题很模糊,我真的迷路了。几个月之后,这是我的答案,希望它可以帮助那些处于我过去职位的人。

当我调用getLoaderManager()。initLoader()或者对内容提供者进行了更改时(内容提供者必须调用getContentResolver()。notifyChange()才能使用),会自动调用onCreateLoader()。我提供了代码来覆盖方法LoaderManager.LoaderCallbacks.onCreateLoader()时创建游标加载器。游标加载器自动传递给onLoadFinished()。就是这样,我不再触摸光标加载器。 onLoadFinished(),它被自动调用,接收一个游标(由游标加载器构成)作为参数。我使用cursor参数this.adapter.setCursor(cursor)更新了onLoadFinished()的覆盖中的适配器。

SimpleCursorAdapter没有moveToNext或moveToPrevious,所以我制作了SteppedAdapter,见下文:

public class SteppedAdapter {
    private Cursor cursor = null;
    // This class uses a reference which may be changed
    // by the calling class.
    public SteppedAdapter (Cursor cursor) {
    this.cursor = cursor;
    }

    private int getColumnIndexOrThrow (String columnName) {
    return cursor.getColumnIndexOrThrow(columnName);
    }   

    public void moveToNext () {     
    if (null != cursor && !cursor.isClosed()) {
        if (cursor.isLast()) {
            cursor.moveToFirst();
        }
        else {
            cursor.moveToNext();
        }
    }   
    }

    public void moveToPrevious () {
    if (null != cursor && !cursor.isClosed()) {
        if (cursor.isFirst()) {
            cursor.moveToLast();
        }
        else {
            cursor.moveToPrevious();
        }
    }
    }

    public String getCurrentTarget (String targetColumn) throws EmptyCursorException {
    int idx = cursor.getColumnIndex(targetColumn);  
    String value = null;
    try {
        value = cursor.getString(idx);  
    }
    catch (CursorIndexOutOfBoundsException e){
        if ( 0 == cursor.getCount()) {
            throw new EmptyCursorException("Cursor is empty: "+e.getMessage()); 
        }
        else {
            throw e;
        }
    }
    return value;
    }   

    public void setCursor (Cursor cursor) {
    this.cursor = cursor;
    }

    public void setCursorToNull () {
    this.cursor = null; 
    }

    public int getPosition () {
    return this.cursor.getPosition();
    }

    public boolean cursorIsClosed () {
    return this.cursor.isClosed();
    }   

    public int getCount () {
    return cursor.getCount();
    }
} // end

由于使用方法adapter.setCursor(Cursor)在onLoadFinished()中设置了适配器,并使用adapter.setCursorToNull()方法在onLoaderReset()中清除。然后适配器必须有这些方法。