0

好吧,我已经阅读了近 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);
}

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

我已经尝试过 notifyDataSetChanged(在 ui 线程上运行)、无效、重新查询(已弃用)......几乎所有内容。

我做错了什么?

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

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;
    }
}
4

2 回答 2

0

如果您不想使用requery(),您可以简单地使用相同的查询传递一个新的 Cursor:

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();
}

如果这“不起作用”,请更具体。它会抛出错误吗,如果是这样,那是什么样的?


您在适配器中做了太多的工作。请在 Google Talks 上观看 Android 的 Romain Guy 讨论适配器和getView(). 但是,由于您只想将一个特殊字符串传递给您的createdOnTextView,让我们做一些非常不同的事情并覆盖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 的现有方法处理。

于 2012-09-13T18:36:25.223 回答
0

我不太了解 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);
于 2012-09-13T18:30:24.903 回答