SimpleCursorAdaptor替代用于在ListView中显示SQLite记录

时间:2016-01-01 22:01:52

标签: android sqlite listview

不推荐使用SimpleCursorAdaptor。我发现它不适合我,因为它使用UI线程,我将显示几百条记录。我想使用一些使用后台线程的东西。经过一番研究,我遇到了CursorLoader。我一直在寻找教程,但我发现实施它真的很棘手。如果有更好的替代CursorLoader,请告诉我。请有人帮助我。我到目前为止的代码。是:

public void getListFromDb(){
    Cursor res = myDb.ViewAll();
    startManagingCursor(res);


    //Map cursor from db to viewFields
    String[] fromFieldNames = new String[]{DatabaseHelper.COL_2, DatabaseHelper.COL_3, DatabaseHelper.COL_4, DatabaseHelper.COL_5};
    int[] toViewIDS = new int[]{R.id.viewName, R.id.viewAddress, R.id.viewPostcode, R.id.viewType};

    //Create adaptor to map items from DB to UI
    SimpleCursorAdapter myCursorAdaptor = new SimpleCursorAdapter(this, R.id.item_layout, res, fromFieldNames, toViewIDS);

    // Set adaptor for listView
    ListView myList = (ListView) findViewById(R.id.listViewLocations);
    myList.setAdapter(myCursorAdaptor);

}

1 个答案:

答案 0 :(得分:1)

实际上只有一个SimpleCursorAdapter构造函数被描述,而不是整个类。你仍然可以使用它,但你必须使用"标准"构造函数需要"标志的值#34;参数。

public void getListFromDb(){
    Cursor res = myDb.ViewAll();
    startManagingCursor(res);


    //Map cursor from db to viewFields
    String[] fromFieldNames = new String[]{DatabaseHelper.COL_2, DatabaseHelper.COL_3, DatabaseHelper.COL_4, DatabaseHelper.COL_5};
    int[] toViewIDS = new int[]{R.id.viewName, R.id.viewAddress, R.id.viewPostcode, R.id.viewType};

    //Create adaptor to map items from DB to UI
    // *** ADD THE FLAGS PARAMETER ***
    SimpleCursorAdapter myCursorAdaptor = new SimpleCursorAdapter(this, R.id.item_layout, res, fromFieldNames, toViewIDS, FLAG_AUTO_REQUERY);

    // Set adaptor for listView
    ListView myList = (ListView) findViewById(R.id.listViewLocations);
    myList.setAdapter(myCursorAdaptor);

}

我已添加" FLAG_AUTO_REQUERY"使变化显而易见,但我怀疑你可能想要使用值" 0" (无标志),除非您的数据在显示时可以更改。

所以在重新阅读你的问题后(​​抱歉,我的不好;我应该更仔细地阅读:-p)你真正的问题是如何在后台线程上加载数据。有很多方法可以做到这一点,都有好的和坏的。

这个经典Android问题有两个部分: 1:实际上在后台线程上加载数据并将结果交给UI线程进行显示。 2:通常由轮换导致的活动破坏/恢复(但可能由收到的电话无法控制的事件引起)。

CursorLoaders笨拙且难以实现,但确实很好地解决了这两个问题..

AsyncTasks将处理后台执行并将结果传递给ui线程并且如果你不关心问题2就可以正常工作,但是在android中有一个令人讨厌的小问题,只能导致一个问题AsyncTask一次运行(如果你想并行完成大量工作,那就太好了。)

还有其他框架可以用来做这种工作,比如rxJava和otto,但是他们需要付出相当大的努力才能最初适应(尽管可以说是值得的)。

如果您需要担心应用程序的轮换和/或中断,我建议CursorLoaders最初可能是最简单的,但仅适用于更简单的应用程序。如果您的应用程序变得复杂,请花些时间查看rxJava或Otto。

希望这会有所帮助。 附:简单的asynctask为基础的例子(避免经过测试,因为我没有你所有的资源/资源,但你明白了。)

public void getListFromDb(){

        //Map cursor from db to viewFields
        String[] fromFieldNames = new String[]{DatabaseHelper.COL_2, DatabaseHelper.COL_3, DatabaseHelper.COL_4, DatabaseHelper.COL_5};
        int[] toViewIDS = new int[]{R.id.viewName, R.id.viewAddress, R.id.viewPostcode, R.id.viewType};


        // Notice I am passing null as the cursor..
        SimpleCursorAdapter myCursorAdaptor = new SimpleCursorAdapter(this, R.id.item_layout, null, fromFieldNames, toViewIDS, 0);
        // Set adaptor for listView
        ListView myList = (ListView) findViewById(R.id.listViewLocations);
        myList.setAdapter(myCursorAdaptor);

        new AsyncTask<SimpleCursorAdapter, Void, Cursor>() {
            private SimpleCursorAdapter mSimpleCursorAdapter;
            @Override
            protected Cursor doInBackground(SimpleCursorAdapter... params) {
                // Save cursorAdapter to use in postExecute
                this.mSimpleCursorAdapter = params[0];
                // Load cursor on background thread
                return myDb.ViewAll();
            }

            @Override
            protected void onPostExecute(Cursor cursor) {
                super.onPostExecute(cursor);
                // and update the cursor (which is already in the listview)
                this.mSimpleCursorAdapter.changeCursor(cursor);
            }
        }.execute(myCursorAdaptor);

    }

主要&#34;技巧&#34;我最初是用null游标创建simplecursoradapter;这允许我在屏幕上获取没有数据的列表。然后我启动一个AsyncTask,将cursoradapter传递给它并让它将光标加载到后台线程上。然后我打电话给&#34; changeCursor&#34;在适配器上,它应该使用加载的数据更新列表视图。您还可以使用onPreExecute来显示忙碌的&#34;微调器&#34;并隐藏繁忙的&#34;旋转器&#34;在onPostExecute ..只是为了让用户知道你正在做某事......哦,以防万一你错过了; onPreExecute和onPostExecute在UI线程上运行,因此可以更新UI,doInBackground在后台线程上运行..