Question

I am trying to modify an example of a listview that is connected to a database. it was setup to only allow for one item in the listview to be selected and then for the user to click a "delete person" button. I have made changes that I thought would allow a user to select multiple people and then click delete and have it delete the items in list selected (checked) and then when the user clicks the delete button to go through a for loop and for the items that are checked to get their id and call the database and delete that row or item from the database table. The code runs and deletes items but it deletes the wrong items and only part of the selected items. I know it has something to do with the way I am checking for the id of the selected (checked) items in the list, but I don't know how to fix it. Please see the code in the onDeleteClick() method.

The source code for the main activity:

public class MainActivity extends ListActivity {

private static final int ADD_DIALOG = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final ListView list = getListView();
    list.setItemsCanFocus(false);
    //list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

    // initialize the adapter
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
            //android.R.layout.simple_list_item_single_choice,
            android.R.layout.simple_list_item_multiple_choice,
            null,
            new String[]{DBHelper.C_NAME},
            new int[]{android.R.id.text1});

    setListAdapter(adapter);
    updateAdapterData();

    }

public void updateAdapterData(){

        // re-query the data
        SQLiteDatabase db = new DBHelper(this).getReadableDatabase();
        //SQLiteDatabase db = new DBHelper(this).getWritableDatabase();
        Cursor c = db.query(DBHelper.TABLE_PEOPLE, null, null, null, null, 
null, null);
        ((SimpleCursorAdapter)getListAdapter()).changeCursor(c);
        db.close();

    }

public void onAddClicked(View view){
    showDialog(ADD_DIALOG);
}

public void onDeleteClicked(View view){

    ListView lstView = getListView(); // added for hw



    //int position = getListView().getCheckedItemPosition(); // removed for hw

    SQLiteDatabase db = new DBHelper(this).getWritableDatabase();

    for(int i = 0; i < lstView.getCount(); i++){

        if(lstView.isItemChecked(i)){

            long itemId = lstView.getItemIdAtPosition(i);
            int rowsAffected = db.delete(DBHelper.TABLE_PEOPLE, 
DBHelper.C_ID + " = " + itemId, null);

        }
    }

    db.close();
    //if(rowsAffected > 0)
        updateAdapterData();

    //if(position >= 0){
        //long itemId = getListAdapter().getItemId(position);
        //SQLiteDatabase db = new DBHelper(this).getWritableDatabase();
        //int rowsAffected = db.delete(DBHelper.TABLE_PEOPLE, DBHelper.C_ID 
+ " = " + itemId, null);
        //db.close();
        //if(rowsAffected > 0)
        //  updateAdapterData();
    //}

}

protected Dialog onCreateDialog(int id){
    Dialog d;
    switch(id){
    case ADD_DIALOG:
        d = new Dialog(this);
        d.setContentView(R.layout.add_person_dialog);
        d.setTitle("Add a Person");
        final TextView nameText = (TextView)d.findViewById(R.id.name);
        d.findViewById(R.id.okay_btn).setOnClickListener(new 
View.OnClickListener() {

            @Override
            public void onClick(View v) {
                addPerson(nameText.getText().toString());
                dismissDialog(MainActivity.ADD_DIALOG);

            }
        });

        d.findViewById(R.id.cancel_btn).setOnClickListener(new 
View.OnClickListener() {

            @Override
            public void onClick(View v) {
                dismissDialog(MainActivity.ADD_DIALOG);

            }
        });
        break;
        default:
            d = super.onCreateDialog(id);
            break;
    }
    return d;
}

public void addPerson(String name){
    // add the new data to the db
    DBHelper helper = new DBHelper(this);
    SQLiteDatabase db = helper.getWritableDatabase();
    ContentValues cv = new ContentValues();
    cv.put(DBHelper.C_NAME, name);
    db.insert(DBHelper.TABLE_PEOPLE, null, cv);
    db.close();

    // update the view
    updateAdapterData();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

}

source code for database helper class:

public class DBHelper extends SQLiteOpenHelper {

private static final String DB_NAME = "myDatabase.db";
private static final int DB_VERSION = 1;

public static final String TABLE_PEOPLE = "people";
public static final String C_ID = "_id";
public static final String C_NAME = "name";

public DBHelper(Context context){
    super(context, DB_NAME, null, DB_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {

    final String sqlCreateTablePeople = "CREATE TABLE "
            + TABLE_PEOPLE + "( " + C_ID
            + " integer primary key autoincrement, " + C_NAME
            + " text not null);";
    db.execSQL(sqlCreateTablePeople);

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    final String sqlDropTablePeople = "DROP TABLE IF EXISTS " + TABLE_PEOPLE + 
";";
    db.execSQL(sqlDropTablePeople);
    onCreate(db);

}

}

the layout for the main activity:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >

<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <Button 
        android:id="@+id/add_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Add Person"
        android:onClick="onAddClicked"
        />

    <Button 
        android:id="@+id/delete_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Delete Person"
        android:onClick="onDeleteClicked"
        />

    </LinearLayout>

    <ListView 
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        ></ListView>


</LinearLayout>

the layout for the add person dialog:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<EditText 
    android:id="@+id/name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Name"
    />

<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <Button 
        android:id="@+id/okay_btn"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Okay"
        />

    <Button 
        android:id="@+id/cancel_btn"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Cancel"
        />

</LinearLayout>

</LinearLayout>
Was it helpful?

Solution

Try using getCheckedItemIds()

public void onDeleteClicked(View view){

    long[] positions = getListView().getCheckedItemIds();

    SQLiteDatabase db = new DBHelper(this).getWritableDatabase();

    for(int i = 0; i < positions.length; i++){

        int rowsAffected = db.delete(DBHelper.TABLE_PEOPLE,
                           DBHelper.C_ID + " = " + positions[i], null);

    }

    db.close();
    if(rowsAffected > 0)
        updateAdapterData();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top