简体   繁体   中英

How to delete item from ListView and SQLite database?

I use AbsListView.MultiChoiceModeListener to select one or any items and delete from ListView (List) and SQLite database. ListView is populated by data from other activity normally. By code as below the method onActionItemClicked(ActionMode mode, MenuItem item) only deletes the last item from list. How to select and delete items from list and SQLite database and update list in this Activity?

DatabaseHelper.class

public class DatabaseHelper extends SQLiteOpenHelper {

    private static final String TABLE_NAME = "value_table";
    private static final String COL1 = "ID";
    private static final String COL2 = "name";

    public DatabaseHelper(Context context/*, String name, SQLiteDatabase.CursorFactory factory, int version*/) {
        super(context, TABLE_NAME, null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String createTable = "CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COL2 +" TEXT)";
        db.execSQL(createTable);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP IF TABLE EXISTS " + TABLE_NAME);
        onCreate(db);
    }
    public boolean addData(String item) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(COL2, item);

        long result = db.insert(TABLE_NAME, null, contentValues);

        //if date as inserted incorrectly it will return -1
        if (result == -1) {
            return false;
        } else {
            return true;
        }
    }
    public Cursor getData(){
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "SELECT * FROM " + TABLE_NAME;
        Cursor data = db.rawQuery(query, null);
        return data;
    }
    public Cursor getItemID(String name){
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "SELECT " + COL1 + " FROM " + TABLE_NAME +
                " WHERE " + COL2 + " = '" + name + "'";
        Cursor data = db.rawQuery(query, null);
        return data;
    }

    /**
     * Updates the name field
     * @param newName
     * @param id
     * @param oldName
     */
    public void updateName(String newName, int id, String oldName){
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "UPDATE " + TABLE_NAME + " SET " + COL2 +
                " = '" + newName + "' WHERE " + COL1 + " = '" + id + "'" +
                " AND " + COL2 + " = '" + oldName + "'";
        db.execSQL(query);
    }

    /**
     * Delete from database
     * @param id
     * @param name
     */
    public void deleteName(int id, String name){
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "DELETE FROM " + TABLE_NAME + " WHERE "
                + COL1 + " = '" + id + "'" +
                " AND " + COL2 + " = '" + name + "'";
        db.execSQL(query);
    }
    public void remove(int id){
        SQLiteDatabase db = this.getWritableDatabase();
        String query = "DELETE FROM " + TABLE_NAME + " WHERE "
                + COL1 + " = '" + id + "'";
        db.execSQL( query);
    }
}

ListDataActivity.class

  public class ListDataActivity extends AppCompatActivity{

    DatabaseHelper mDatabaseHelper;
    private ListView mListView;
    ArrayList<String> listData;
    ArrayList<String> UserSelection = new ArrayList<>();
    ArrayList<Integer> listDataSelect;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_layout);
        mListView = (ListView) findViewById(R.id.listView);
        mListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL);
        mListView.setMultiChoiceModeListener(modeListener);
        mDatabaseHelper = new DatabaseHelper(this);

        populateListView();
    }
    private void populateListView() {
        //get the data and append to a list
        Cursor data = mDatabaseHelper.getData();
        listData = new ArrayList<>();
        while (data.moveToNext()) {
            //get the value from the database in column 1
            //then add it to the ArrayList
            listData.add(data.getString(1));
        }
        //create the list adapter and set the adapter
        ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listData);
        mListView.setAdapter(adapter);
    }
    private void toastMessage(String message){
        Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
    }
    AbsListView.MultiChoiceModeListener modeListener=new AbsListView.MultiChoiceModeListener() {
        @Override
        public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {

            if (UserSelection.contains(listData.get(position))) {
                UserSelection.remove(listData.get(position));
            } else {
                UserSelection.add(listData.get(position));
            }
            mode.setTitle(UserSelection.size() + " items selected....");

            String name=listData.get(position);
            Cursor data = mDatabaseHelper.getItemID(name);
            int itemID = -1;
            while(data.moveToNext()){
                itemID = data.getInt(0);
                listDataSelect.add(itemID);
            }

        }
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            MenuInflater menuInflater=mode.getMenuInflater();
            menuInflater.inflate(R.menu.menu_context,menu);
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return true;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()){
                case R.id.menu_delete:
                     for(int i=0; i<listDataSelect.size();i++){
                        mDatabaseHelper.remove(listDataSelect.get(i));
                     }
                break;
            }
            return true;
        }
        @Override
        public void onDestroyActionMode(ActionMode mode) {
        }
    };
}

Look, in onActionItemClicked(..) by calling this line:
mDatabaseHelper.remove(pos);
you delete only item with value of pos . There are several problems in your code, especially assigning item id (id populated from listView, not id database) and passing as argument to remove() global variable.
Let me clarify what I said. Starting from remove() from your dbHelper class it deletes row where table id equals passed id . The problem is that you pass ListView item id so that if the user has more items or made already a lot of operation it will throw an exception or will not delete because there is not such id in your database.
To sum up, all you have to do by passing argument to this method is pass databaseId as an argument (you can get this id by creating additional method).

Secondly, in your onItemCheckedChanged() you can't assign a new value to global variable. Every time you check a new item a variable changes. This is the reason why last item is being deleted or random one (although not random).

Okay, it looks like a long text containing lots of understanding but the solution is much more easier than you think.

In onItemCheckedStateChanged() every time get database row id and pass it to a global list. Currently you pass item id . Then in onActionItemClicked() run for loop calling method remove() from Helper class and pass item from List as an argument.
That's all!

BTW consider using RecyclerView instead of ListView - it's much better and newer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM