从适配器刷新列表视图

Refresh listview from adapter

我有 2 个列表 CheckBox。当用户勾选 list_1 中的 CheckBox 时,列表项将转移到 list_2。它工作正常,除了我无法从适配器刷新列表。尝试使用 notifyDataSetChanged() 但没有任何反应。

在我的 MainActivity:

CustomListAdapter adapter = new CustomListAdapter(this, db.getAllTasks(MySQLiteHelper.TABLE_HOME, false), MySQLiteHelper.TABLE_HOME,false);
mylistView.setAdapter(adapter);    // Set the adapter for list_1

CustomListAdapter adapterDone = new CustomListAdapter(this, db.getAllTasks(MySQLiteHelper.TABLE_HOME, true),  MySQLiteHelper.TABLE_HOME,true);
listViewDone.setAdapter(adapterDone);    // Set the adapter for list_2

getAllTasks 函数:

public List<Task> getAllTasks(String tableName, boolean done) {
    List<Task> tasks = new LinkedList<Task>();

    String op = done ? "1" : "0";
    String query = "SELECT  * FROM " + tableName + " WHERE done=" + op;
    Log.d(TAG, "query: " + query);
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(query, null);
    Task task = null;

    if (cursor.moveToFirst()) {
        do {
            task = new Task();
            task.setTaskText(cursor.getString(0));
            task.setDate(cursor.getString(1));
            task.setTime(cursor.getString(2));
            task.setDone(cursor.getInt(3) == 1);
            tasks.add(task);
        } while (cursor.moveToNext());
    }

    return tasks;
}

这是我的 Adapter:

public class CustomListAdapter extends ArrayAdapter<Task> {
    private static final String TAG = "DTAG";
    private final Activity context;
    private final List<Task> myTasks;
    private final MySQLiteHelper db;
    private final String tableName;
    private final boolean done;

    public CustomListAdapter(Activity context, List<Task> myTasks, String tableName, boolean done) {
        super(context, R.layout.list_row, myTasks);

        this.context = context;
        this.myTasks = myTasks;
        this.tableName = tableName;
        this.done = done;
        db = new MySQLiteHelper(context);
    }

    public View getView(final int position, View view, ViewGroup parent) {
        LayoutInflater inflater = context.getLayoutInflater();
        View rowView = inflater.inflate(R.layout.list_row, null, true);

        final TextView txtTitle = (TextView) rowView.findViewById(R.id.listMainTextView);
        TextView txtSubTitle = (TextView) rowView.findViewById(R.id.listSubTextView);

        CheckBox ch = (CheckBox) rowView.findViewById(R.id.checkBox);
        ch.setChecked(done);

        ch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    Log.d(TAG, "position: " + position + " Name: " + myTasks.get(position).getTaskText() + " Checked");
                    db.updateTask(myTasks.get(position).getTaskText(), tableName, true);
                } else {
                    Log.d(TAG, "position: " + position + " Name: " + myTasks.get(position).getTaskText() + " UnChecked");
                    db.updateTask(myTasks.get(position).getTaskText(), tableName, false);
                }

                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        notifyDataSetChanged();
                    }
                }, 1000);
            }
        });

        txtTitle.setText(myTasks.get(position).getTaskText());
        txtSubTitle.setText(myTasks.get(position).getTime() + " " + myTasks.get(position).getDate());

        return rowView;
    };
}

您必须在更新数据库后再次调用 get task 以获取新的任务列表,然后调用 notifydatasetchange。
在这种情况下,我个人使用 cursoradapter,更改后,重新查询我的光标并调用 changecursor。
希望对你有帮助。

像这样在 MainActivity 中创建两个单独的 Task 列表。

List<Task> tasksPendingList = new LinkedList<Task>();
List<Task> tasksDoneList = new LinkedList<Task>();

现在通过在初始化 Adapter 之前调用 getAllTasks 方法来获取任务。

tasksPendingList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, false);
tasksDoneList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, true);

现在像这样初始化适配器

CustomListAdapter adapter = new CustomListAdapter(this, tasksPendingList, MySQLiteHelper.TABLE_HOME, false);
mylistView.setAdapter(adapter);    // Set the adapter for list_1

CustomListAdapter adapterDone = new CustomListAdapter(this, tasksDoneList,  MySQLiteHelper.TABLE_HOME, true);
listViewDone.setAdapter(adapterDone);    // Set the adapter for list_2

现在,在 AdaptergetView 方法中,您需要再次重新填充列表才能使 notifyDatasetChanged 正常工作。

 ch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            db.updateTask(myTasks.get(position).getTaskText(), tableName, true);
        } else {
            db.updateTask(myTasks.get(position).getTaskText(), tableName, false);
        }

        // Just call refreshBothList here
        refreshBothList();
    }
});

您可以考虑在 MainActivity 中的 getView 方法之外采用列表的刷新机制。

public void refreshBothList() {
    // Repopulate the lists. 
    tasksPendingList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, false);
    tasksDoneList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, true);

    adapter.notifyDataSetChanged();
    adapterDone.notifyDataSetChanged();
}

您可以考虑将 CustomListAdapter 作为内部 class 放入 MainActivity