从数据库更新List视图

时间:2012-11-15 10:33:58

标签: android android-listview android-sqlite

我觉得我错过了简单而愚蠢的事情。我有一个列表视图,顶部有几个按钮。列表视图最初填充了数据。单击按钮时,列表视图应根据Where语句中已更改的变量填充其自身。实际上我可能只是开始一个新的List活动,但我觉得有更好的方法。

我一直在阅读CursorAdapter.changeAdapter()notifydatasetchanged()我还没有实现这个,因为我有一个更基本的问题。

我可以成功查询数据库并在列表中显示静态结果。当我尝试将进程分解为步骤时,我遇到了错误:fillWindow中的语句无效。我理解的最好的原因是不正确关闭游标数据库和数据库帮助程序,因此人们使用内容提供程序。

现在我只想让它发挥作用。

    public class DListView extends ListActivity implements OnClickListener{

public static final String NAME = "Name";

public static final String DESCRIPT = "Description";

public static final String DATABASE_TABLE = "Table";


public static final String DAY = "Day_id";

    /** Called when the activity is first created. */
private Cursor c = null;    

private String[] colsfrom = {"_id", NAME, DESCRIPT, DAY};
private int[] to = new int[] {R.id.text01, R.id.text02, R.id.text03, R.id.text04};

public int b = 0;

public int d = 0; 

   @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.drinklistview);

        View left = findViewById(R.id.left_button);
        left.setOnClickListener(this);
        View right = findViewById(R.id.right_button);
        right.setOnClickListener(this);

        Intent thisIntent = getIntent();
        b = thisIntent.getIntExtra("_b", 0); 
        //0 is the default argument is nothing is passed.
        d = thisIntent.getIntExtra("_d", 0); //same idea as above.

            c = fillList(); 

            /*this creates a new cursor adapter
            @param Context is the list context that you will be filling. 
            @param int layout is the layout that you will use for the rows
            @param Cursor is the cursor that was returned from the query
            @param from is the column names
            @param to is the layout ids that the fields will be put in. 
            @param from is the column names to map from
            @param to is the layout ids that the column fields will be put in. 
            */
            SimpleCursorAdapter myAdapter = new SimpleCursorAdapter(this, R.layout.row, c, colsfrom, to);
            setListAdapter(myAdapter);
   }

private Cursor fillList() {
    DBHelper DbHelper = new DBHelper(this);
    Cursor cursor;
    String wHERE = "_id = " + b + " AND Day_id = " + d ; 

    try {
        myDbHelper.openDataBase();  
    }
    catch(SQLException sqle){
        throw sqle; 
    }

    cursor = myDbHelper.getDrinks(DATABASE_TABLE, colsfrom, wHERE, null, null,null, null);

    myDbHelper.close();

    return cursor;

}

当我将fillList()的内容放在onCreate()中时,它显示数据就好了。当我把它拉出来时,它给了我错误。为什么会这样?如果有人有更好的方法来解决这个问题,我很乐意阅读它。或者我们可以玩一个名为“我做错了什么愚蠢的事情现在? 三江源。

编辑:来自DBHelper

public void openDataBase() throws SQLException{

    //Open the database
    String myPath = DB_PATH + DB_NAME;
    myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}

    @Override
    public synchronized void close() {

        if(myDataBase != null)
            myDataBase.close();
        super.close();
    }

我认为我的问题行是super.close()我相信这行关闭数据库及其附属的任何东西,这意味着我在关闭后尝试使用的游标。我可能错了。请解释一下你是否可以。

2 个答案:

答案 0 :(得分:0)

您的问题就在这里,在fillList()

myDbHelper.close(); // <--- here
return cursor;

你创建一个游标对象但是在你使用它之前关闭你的数据库连接(数据库的这个组件),如果你愿意,它会使它无用或为null。通常关闭光标然后数据库。但这并没有抛出错误。那个错误特别是是因为你将这个光标连接到一个cursorAdapter,试图用什么来填充你的listView。移动它,它应该消失。

那么你搬到哪里呢?如果你有一个连接到listView的游标,它需要在整个时间打开,否则你会收到另一个错误,说“尝试重新打开已经关闭的对象”。我建议放入onDestroy()然后再查看listView。

答案 1 :(得分:0)

YaY解决了。芒果是完全正确的。谢谢你的建议,关闭光盘在破坏。我不确定super.close()行是否关闭了我的光标。但我会调查一下。我也打算将数据库查询放在异步任务中,以解决问题和傻笑。

我只是移动了创建新SimpleCursorAdapter的两行,并将列表视图设置为fillList方法。

我还实现了我的按钮,最后添加了fillList。 这是解决问题的代码。简单的错误。

private void fillList() {
DBHelper DbHelper = new DBHelper(this);
Cursor cursor;
String wHERE = "_id = " + b + " AND Day_id = " + d ; 

try {
    myDbHelper.openDataBase();  
}
catch(SQLException sqle){
    throw sqle; 
}

cursor = myDbHelper.getDrinks(DATABASE_TABLE, colsfrom, wHERE, null, null,null, null);
SimpleCursorAdapter myAdapter = new SimpleCursorAdapter(this, R.layout.row, cursor, colsfrom, to);
setListAdapter(myAdapter);
myDbHelper.close();
 }

这是我再次调用fillList来更新我的列表视图。

 public void onClick(View v) {
    switch(v.getId()) {

    //Mess with d based on button click
    }
    fillList();
}

现在,每次更改内容时,应用程序都必须创建一个新的简单游标适配器。 如果有人在没有创建新CursorAdapter的情况下有任何实现这一点的想法,那么每次都会有很大帮助,但我的初始问题已经解决了。谢谢您的帮助。事实上,你想看到我的堆栈跟踪告诉我,我在最初提出的代码中没有做任何错误,我忘了我让我的dbHelper关闭所有连接。谢谢芒果。我昨晚解决了这个问题,但无法发布。谢谢你的解释好先生。如果您对不断创建新的cursoradapter有任何见解,我会很高兴看到它。也许我需要以某种方式修复super.close()命令。