首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android CursorAdapter ListView 中刪除項目並同步數據庫的正確實現

     編輯:程式設計綜合問答

問題場景

CursorAdapter 綁定 ListView,每行含刪除按鈕。點擊按鈕需:獲取該行數據庫 ID → 刪除數據庫記錄 → 更新 Cursor → 刷新列表。

正確實現:bindView 中獲取 ID、刪除後 requery + notifyDataSetChanged


public class MyAdapter extends CursorAdapter {
    private Context context;
    private DatabaseHelper dbHelper;

    public MyAdapter(Context context, Cursor c, DatabaseHelper helper) {
        super(context, c, 0);
        this.context = context;
        this.dbHelper = helper;
    }

    @Override
    public void bindView(View view, Context context, final Cursor cursor) {
        TextView name = view.findViewById(R.id.txt_name);
        name.setText(cursor.getString(cursor.getColumnIndex(DatabaseHelper.COL_NAME)));

        Button deleteBtn = view.findViewById(R.id.btn_delete);
        deleteBtn.setOnClickListener(v -> {
            // 1. 獲取當前行的數據庫主鍵 ID
            long itemId = cursor.getLong(cursor.getColumnIndex(DatabaseHelper.COL_ID));

            // 2. 刪除數據庫記錄
            dbHelper.deleteRecord(itemId);

            // 3. 重新查詢 Cursor 並通知適配器刷新
            Cursor newCursor = dbHelper.getAllRecords();
            changeCursor(newCursor); // CursorAdapter 方法,自動關閉舊 Cursor
            notifyDataSetChanged();
        });
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(R.layout.row, parent, false);
    }
}

關鍵點

  • 在 bindView 閉包中捕獲 cursor:每行綁定時 cursor 已移動到對應位置,直接 cursor.getLong(COL_ID) 獲取該行 ID。
  • 使用 changeCursor(newCursor):CursorAdapter 專用方法,安全關閉舊 Cursor、設置新 Cursor、觸發觀察者更新。
  • 數據庫操作放背景線程:實際項目中刪除應用 AsyncTask/Executor/Room 異步執行,成功後回主線程 changeCursor。

現代替代:RecyclerView + Room + ListAdapter


// Room DAO
@Query("DELETE FROM table WHERE id = :id")
void deleteById(long id);

@Query("SELECT * FROM table")
LiveData> getAll();

// ViewModel
LiveData> entities = repository.getAll();

// Activity/Fragment
ListAdapter adapter = new ListAdapter<>(DIFF_CALLBACK);
adapter.submitList(entities.getValue()); // 或 observe

// ViewHolder 刪除按鈕
deleteBtn.setOnClickListener(v -> {
    long id = getItem(getBindingAdapterPosition()).getId();
    viewModel.delete(id); // 觸發數據庫刪除 -> LiveData 更新 -> adapter 自動動畫刷新
});

無需手動管理 Cursor、notifyDataSetChanged,DiffUtil 自動計算最小更新並執行動畫。

總結

CursorAdapter 刪除項目核心模式:**bindView 獲取 ID → 異步刪除數據庫 → changeCursor(newCursor) + notifyDataSetChanged()**。新項目強烈建議遷移至 Room + RecyclerView + ListAdapter,獲得類型安全、異步安全、動畫自動化的現代體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved