【问题标题】:deleting an item from listview (using sqlite) results in only removing it from listview.Can't delete it from database从 listview 中删除一个项目(使用 sqlite)只会将它从 listview 中删除。不能从数据库中删除它
【发布时间】:2013-04-12 19:16:45
【问题描述】:

当我尝试删除列表视图中的项目时,它会从列表视图中删除它,但是当我添加新项目或再次运行应用程序时,项目仍然存在。我无法从数据库中删除它。

我正在使用此代码:

...
SqlHandler sqlHandler;
ListView myListView;
myAdapter adapter;
ArrayList<myItems> items;
 ...
 myListView = (ListView) findViewById(R.id.myListView);
 sqlHandler = new SqlHandler(this);
 items = getItemsFromDatabase();

adapter = new myAdapter(this, items);
myListView.setAdapter(adapter);
myListView.setOnItemLongClickListener(this);
 ...
public boolean onItemLongClick(AdapterView<?> adapterView, View view,
        int position, long id) {

    final myItems selectedItem = items.get(position);

    if (selectedItem != null) {
        AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
        alt_bld.setMessage("Do you want to delete this item?")
                .setCancelable(false)
                .setPositiveButton("Yes",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int id) {

                                sqlHandler=new SqlHandler(getApplicationContext());
                                sqlHandler.deleteRecord(id);
                                items.remove(selectedItem);
                                adapter.notifyDataSetChanged();

对于我使用的数据库:

public class SqlHandler {
    public static final String DATABASE_NAME = "MY_DATABASE";
    public static final String DATABASE_TABLE = "MEM";
    public static final String KEY_ROWID = "_id";

        public static final int DATABASE_VERSION = 1;
            Context context;
            SQLiteDatabase sqlDatabase;
            SqlDbHelper dbHelper;

            public SqlHandler(Context context) {

                 dbHelper = new SqlDbHelper(context, DATABASE_NAME, null,
                   DATABASE_VERSION);
                 sqlDatabase = dbHelper.getWritableDatabase();
                }

    public void executeQuery(String query) {
     try {

      if (sqlDatabase.isOpen()) {
       sqlDatabase.close();
      }

      sqlDatabase = dbHelper.getWritableDatabase();
      sqlDatabase.execSQL(query);

     } catch (Exception e) {

      System.out.println("DATABASE ERROR " + e);
     }

}

        public Cursor selectQuery(String query) {
         Cursor c1 = null;
         try {

          if (sqlDatabase.isOpen()) {
           sqlDatabase.close();

          }
          sqlDatabase = dbHelper.getWritableDatabase();
          c1 = sqlDatabase.rawQuery(query, null);

         } catch (Exception e) {

          System.out.println("DATABASE ERROR " + e);

         }
         return c1;

}
        public SqlHandler open() throws SQLException
        {
            sqlDatabase = dbHelper.getWritableDatabase();
        return this;
        }

        public void Close(){
            dbHelper.close();

        }
        public void  deleteRecord(long rowId){
            try {
             sqlDatabase.delete(DATABASE_TABLE,KEY_ROWID + "="+rowId,null);
            }
            catch (Exception e)
            {
                Log.e("DB ERROR", e.toString());
                e.printStackTrace();
            }
        }

public class SqlDbHelper extends SQLiteOpenHelper {
public static final String DATABASE_TABLE = "MEM";



public static final String TAG="DbHandler";

 public static final String KEY_ROWID = "_id";
 ...


 private static final String SCRIPT_CREATE_DATABASE = "create table "
   + DATABASE_TABLE + " (" + KEY_ROWID
   + " integer primary key autoincrement, " + ....);";

 public SqlDbHelper(Context context, String name, CursorFactory factory,
   int version) {
  super(context, name, factory, version);
  // TODO Auto-generated constructor stub

 }

 @Override
 public void onCreate(SQLiteDatabase db) {
  // TODO Auto-generated method stub
  db.execSQL(SCRIPT_CREATE_DATABASE);

 }

 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  // TODO Auto-generated method stub
     Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
             + newVersion + ", which will destroy all old data");
  db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
  onCreate(db);
 }

---------更新----------

应该是这样的:

myItems theItems =(myItems)adapterView.getItemAtPosition(button_id);
String _id = theItems.getID();
String delQuery = "DELETE FROM MEM WHERE _id='"+_id+"' ";
sqlHandler.executeQuery(delQuery);

但我的 (myItems)adapterView 有问题。我不知道如何处理。

【问题讨论】:

    标签: android sqlite listview


    【解决方案1】:

    你的问题是你的方法 delete 的调用,应该是这样的:

    public long deleteItem(myItems itemToDelete) {
        try {
                 return sqlDatabase.delete(DATABASE_TABLE,COLUMN_ID + " = ?",new String[]{itemToDelete.getID()});
                }
                catch (Exception e)
                {
                    Log.e("DB ERROR", e.toString());
                    e.printStackTrace();
                    return -1;
                }
    }
    

    当您按YESButtonAlertDialog 确认删除时,您应该从数据库中删除该项目,然后从数据库中重新加载项目并通知您的列表适配器以使用新数据刷新它:

    myItems selectedItem = adapter.getItem(position);
    long rows = sqlHandler.deleteItem(selectedItem);
    if(rows>0) {
        //get new items from database 
        adapter.setItems(getItemsFromDatabase());
        adapter.notifyDataSetChanged();
    }
    

    该项目将从数据库中删除,listView 将用新数据刷新

    【讨论】:

      【解决方案2】:

      我相信错误就在这里:

          new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int id) { //<--- rename this to buttonId
                sqlHandler=new SqlHandler(getApplicationContext());
                sqlHandler.deleteRecord(id);  //<---- This "id" is the button that was clicked, not your item ID
      

      我想您想使用 other id 变量,但即便如此,我也不确定这是否是您真正想要的(可能是)。从你的代码中,我无法快速分辨出真实 ID 在哪里。

      【讨论】:

      • 打败我。做一些简单的调试,你的适配器的“行 id”肯定会与你的数据库行 id 不同(具体是什么取决于适配器)。
      • 你使用的是button_id,你需要使用positionmyItems item =(myItems)adapterView.getItemAtPosition(position);
      • @dmon:如果我使用位置,它会说“不能引用非最终...”。我在“new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int button_id) {" 里面是 "public boolean onItemLongClick(AdapterView> adapterView, View view, int position, long id) { final myItems selectedItem = items.get(position);"
      • Make position final...这意味着它在范围内的任何时候都不能改变,这是真的。
      • @dmon: 不,我不能做位置 final "public boolean onItemLongClick(AdapterView> adapterView, View view, int final position, long id) {" 。然后显示问题onItemLongClick 方法。
      猜你喜欢
      • 1970-01-01
      • 2017-12-11
      • 2019-02-02
      • 1970-01-01
      • 1970-01-01
      • 2020-11-14
      • 1970-01-01
      • 1970-01-01
      • 2019-09-26
      相关资源
      最近更新 更多