Android:更新ListView

Android:更新ListView,android,listview,simplecursoradapter,Android,Listview,Simplecursoradapter,好吧,我已经阅读了将近50个与这个问题相关的链接,但是我的代码仍然不起作用 我有一个扩展SimpleCursorAdapter类的自定义适配器,我使用该适配器填充onCreate方法上的ListView private void populateListView() { String[] from = new String[] { SchemaHelper.TASK_DESCRIPTION, SchemaHelper.TASK_CREATED_ON, SchemaHelper.TASK_

好吧,我已经阅读了将近50个与这个问题相关的链接,但是我的代码仍然不起作用

我有一个扩展SimpleCursorAdapter类的自定义适配器,我使用该适配器填充onCreate方法上的ListView

private void populateListView()
{
    String[] from = new String[] { SchemaHelper.TASK_DESCRIPTION, SchemaHelper.TASK_CREATED_ON, SchemaHelper.TASK_ID };

    int[] to = new int[] {R.id.lv_row_description, R.id.lv_row_created_on};

    tasksCursor = schemaHelper.getTasks();

    startManagingCursor(tasksCursor);

    tasksAdapter = new TasksAdapter(this, R.layout.tasks_listview_row, tasksCursor, from, to);

    setListAdapter(tasksAdapter);
}
该应用程序是一个简单的任务管理器,我想在用户提交新任务而不再次调用setListAdapter()时更新ListView内容

我尝试过notifyDataSetChanged(在ui线程上运行)、invalidate、requery(已弃用)。。。几乎所有的东西

我做错了什么

编辑: 这是我向数据库添加新任务的方法

private void addTask(String description)
{
    String message = "";

    schemaHelper.open();

    if(schemaHelper.isAlreadyInDatabase(description))
    {
        message = getString(R.string.task_already_exists);
    }
    else
    {
        message = getString(R.string.task_succesfully_added);

        schemaHelper.insertTask(description);

        populateListView();

        newTask.setText("");
    }

    schemaHelper.close();

    Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
适配器类:

private class TasksAdapter extends SimpleCursorAdapter
{
    private LayoutInflater layoutInflater;

    private Cursor cursor;

    public TasksAdapter(Context context, int layout, Cursor c, String[] from, int[] to)
    {
        super(context, layout, c, from, to);

        cursor = c;

        cursor.moveToFirst();

        layoutInflater = LayoutInflater.from(context);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        if(cursor.getPosition() < 0)
        {
            cursor.moveToFirst();
        }
        else
        {
            cursor.moveToPosition(position); // Here throws the error
        }

        View row = layoutInflater.inflate(R.layout.tasks_listview_row, null);

        TextView description = (TextView) row.findViewById(R.id.lv_row_description);

        TextView createdOn = (TextView) row.findViewById(R.id.lv_row_created_on);

        description.setText(cursor.getString(cursor.getColumnIndexOrThrow(SchemaHelper.TASK_DESCRIPTION)));

        createdOn.setText(getString(R.string.added_on) + " " + TaskHelper.formatDateWithSuffix(cursor.getString(cursor.getColumnIndexOrThrow(SchemaHelper.TASK_CREATED_ON))));

        return row;
    }
}
私有类TasksAdapter扩展了SimpleCursorAdapter
{
私人停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场;
私有游标;
公共任务适配器(上下文上下文、整型布局、光标c、字符串[]从、整型[]到)
{
super(上下文、布局、c、from、to);
光标=c;
cursor.moveToFirst();
layoutInflater=layoutInflater.from(上下文);
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图)
{
if(cursor.getPosition()<0)
{
cursor.moveToFirst();
}
其他的
{
cursor.moveToPosition(position);//这里抛出错误
}
视图行=布局平坦。充气(R.layout.tasks\u listview\u行,空);
TextView description=(TextView)row.findViewById(R.id.lv\u row\u description);
TextView createdOn=(TextView)row.findViewById(R.id.lv\u row\u created\u on);
description.setText(cursor.getString(cursor.getColumnIndexOrThrow(SchemaHelper.TASK_description));
createdOn.setText(getString(R.string.added_on)+“+taskheloper.formatDateWithuffix(cursor.getString(cursor.getColumnIndexOrThrow(SchemaHelper.TASK_CREATED_on)));
返回行;
}
}

我不太了解taskCursor和taskAdapter,但我使用了ArrayAdapter,我想,我们可以看看我的代码,得出自己的结论

               //LISTVIEW database CONTATO
    ListView user = (ListView) findViewById(R.id.lvShowContatos);
    //String = simple value ||| String[] = multiple values/columns
    String[] campos = new String[] {"nome", "telefone"};

    list = new ArrayList<String>();
    Cursor c = db.query( "contatos", campos, null, null, null, null, "nome" + " ASC ");
    c.moveToFirst();
    String lista = "";
    if(c.getCount() > 0) {
        while(true) {
           list.add(c.getString(c.getColumnIndex("nome")).toString());
            if(!c.moveToNext()) break;
        }
    }

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, list);

    user.setAdapter(adapter);

//LISTVIEW数据库CONTATO
ListView用户=(ListView)findViewById(R.id.lvShowContatos);
//字符串=简单值| | |字符串[]=多个值/列
字符串[]campos=新字符串[]{“nome”,“telefone”};
列表=新的ArrayList();
游标c=db.query(“contatos”,campos,null,null,null,“nome”+“ASC”);
c、 moveToFirst();
字符串lista=“”;
如果(c.getCount()>0){
while(true){
添加(c.getString(c.getColumnIndex(“nome”)).toString());
如果(!c.moveToNext())中断;
}
}
ArrayAdapter=新的ArrayAdapter(此,
android.R.layout.simple_list_item_1,list);
user.setAdapter(适配器);

如果您不想使用
requery()
只需通过相同的查询传递一个新光标:

tasksCursor.close();
tasksCursor = schemaHelper.getTasks();
startManagingCursor(tasksCursor);
tasksAdapter.changeCursor(tasksCursor);

我假设当您调用
addTask()
时,您已经调用了
populateListView()
一次。尝试将
addTask()
更改为:

private void addTask(String description)
{
    String message = "";

    schemaHelper.open();

    if(schemaHelper.isAlreadyInDatabase(description))
    {
        message = getString(R.string.task_already_exists);
    }
    else
    {
        message = getString(R.string.task_succesfully_added);

        schemaHelper.insertTask(description);

        // Remove call to populateListView(), just update the Cursor 
        tasksCursor.close();
        tasksCursor = schemaHelper.getTasks();
        startManagingCursor(tasksCursor);
        tasksAdapter.changeCursor(tasksCursor);

        newTask.setText("");
    }

    schemaHelper.close();

    Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
如果这个“不起作用”,请更具体一些。它是否抛出错误,如果是,是什么类型的错误


您在适配器中做的工作有点太多。请观看Android的Romain Guy在谷歌对话中的讨论。但是,由于您只想将一个特殊字符串传递给
createdOn
TextView,因此让我们做一些非常不同的事情,覆盖
setViewText()

试试这个:

public class TasksAdapter extends SimpleCursorAdapter {
    String prefix;
    public TasksAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to) {
        super(context, layout, cursor, from, to);
        // This is constant so set it once and consider adding the space to the end of the String in strings.xml
        prefix = getString(R.string.added_on) + " ";
    }

    @Override
    public void setViewText(TextView v, String text) {
        if(v.getId() == R.id.lv_row_created_on)
            v.setText(prefix + TaskHelper.formatDateWithSuffix(text));
        else
            super.setViewText(v, text);
    }
}

其余数据由SimpleCursorAdapter的现有方法处理。

如何/在何处添加新任务?游标:fillWindow()中的语句无效,并且ListView显示为空。。。是的,当调用addTask()时,populatelistView已经执行。在读取光标之前,我看到您的数据库已关闭,请尝试将
schemaHelper.open()
移动到
onResume()
schemaHelper.close()
移动到
onPause()
。仍然引发相同的错误。。。可能是与打开/关闭光标有关的问题?是的,很好。我更新了答案,明确地关闭了第一个光标。希望这有帮助。嗯,现在抛出一个不同的错误:对字段插槽0的请求不正确。num_rows=0 numcolumns=0,此错误指向适配器。。。