Delete selected item from listview and sqlite Android - java

I am having trouble with my programming project. I am creating a shopping application and all I need is deleting the selected data from listview and mysqlite database with a click of a button. I also created a query on my sqlite where it will delete primary key autoincrement integer.
Here is my class:
public class CartPage extends AppCompatActivity {
DatabaseHelper myDB;
public Button button_delete;
public Button button_home;
public TextView textView_totalAmount;
public TextView textView_PK;
public ListView listView_datas;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cart_page);
myDB = new DatabaseHelper(this);
listView_datas = (ListView) findViewById(R.id.listView_ShoppingData);
button_delete = (Button) findViewById(R.id.button_deleteData);
button_home = (Button) findViewById(R.id.button_HomePage);
textView_totalAmount = (TextView) findViewById(R.id.textView_DisplayTotalAmount);
int total = myDB.addPrice();
textView_totalAmount.setText("$" + Integer.toString(total));
final ArrayList<String> list_cart = new ArrayList<>();
final Cursor data = myDB.getPrice_cart();
if (data.getCount() == 0) {
Toast.makeText(CartPage.this, "The Database is empty..", Toast.LENGTH_LONG).show();
} else {
while (data.moveToNext()) {
list_cart.add(data.getString(1) + "\n" +
data.getString(2) + "\n");
ListAdapter listAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_multiple_choice, list_cart);
listView_datas.setAdapter(listAdapter);
}
}
button_home.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent goHome = new Intent(CartPage.this, FirstPage.class);
startActivity(goHome);
}
});
}
}
Here is my database helper query for deleting the data by primary key
public int deleteSelectedItem(String number){
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(table_Cart,"number = ?" , new String[] {number} );
}
For this scenario I was thinking on using but I am not sure how to do it.
listView_datas.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
});
I also saw where when you hold the selected item it would get deleted. I don't mind that as long as it deletes the data.
Thank you!

I would suggest you implement a long click listener in your ListView and on long click on the item in your list, it will show an option to delete the corresponding item in your list. Here's a sample code that can help you.
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> arg0, View view, final int position, long arg3) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(RecipeList.this);
alertDialog.setTitle("Delete");
alertDialog.setMessage(yourList.get(position));
alertDialog.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
deleteSelectedItem(yourList.get(position))
}
});
alertDialog.show();
return true;
}
});
And yes, you need to call notifyDataSetChanged() in your deleteSelectedItem() function to see the effect of the delete in your list.
public int deleteSelectedItem(String number){
SQLiteDatabase db = this.getWritableDatabase();
int result = db.delete(table_Cart,"number = ?" , new String[] {number} );
// Update your list here
// Remove the deleted item from the list that you have passed to the adapter. Then call notifyDataSetChanged
updateYourListCart();
myAdapter.notifyDataSetChanged();
}

Related

Data deleted from an SQLite Database appear again

I have a bug in my code. Whenever I delete items from my SQ Lite database, the itens are deleted. Although, when I insert a new item, the items who were removed appear again. Can you help me? Sorry to bother, but i don't know what to do.
Here it is my MainActivity.
MainActivity.java
public class MainActivity extends Activity
{
private InputDbHelper mHelper;
private ListView mListView;
private EditText mEditText;
private Button mButton;
ArrayList<String> list = new ArrayList<String>();
ArrayAdapter<String> adapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.button);
mEditText = (EditText) findViewById(R.id.editText);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, list);
mListView=(ListView)findViewById(R.id.listView);
mListView.setAdapter(adapter);
mHelper = new InputDbHelper(this);
updateUI();
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String input = mEditText.getText().toString();
if (input.length() > 0) {
SQLiteDatabase db = mHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(InputContract.TaskEntry.COL_TASK_TITLE, input);
db.insertWithOnConflict(InputContract.TaskEntry.TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.close();
updateUI();
}
}
});
mListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View v, final int position, long id) {
AlertDialog.Builder adb=new AlertDialog.Builder(MainActivity.this);
adb.setTitle("Delete?");
adb.setMessage("Are you sure you want to delete this note?");
final int positionToRemove = position;
adb.setNegativeButton("Cancel", null);
adb.setPositiveButton("Ok", new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
SQLiteDatabase db = mHelper.getWritableDatabase();
db.delete(InputContract.TaskEntry.TABLE, InputContract.TaskEntry._ID + " = ?", new String[] { String.valueOf(positionToRemove)});
list.remove(positionToRemove);
adapter.remove(String.valueOf(positionToRemove));
adapter.notifyDataSetChanged();
}});
adb.show();
}
});
}
private void updateUI() {
ArrayList<String> taskList = new ArrayList<String>();
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor cursor = db.query(InputContract.TaskEntry.TABLE,
new String[]{InputContract.TaskEntry._ID, InputContract.TaskEntry.COL_TASK_TITLE},
null, null, null, null, null);
while (cursor.moveToNext()) {
int idx = cursor.getColumnIndex(InputContract.TaskEntry.COL_TASK_TITLE);
taskList.add(cursor.getString(idx));
}
if (adapter== null) {
adapter= new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,
taskList);
mListView.setAdapter(adapter);
} else {
adapter.clear();
adapter.addAll(taskList);
adapter.notifyDataSetChanged();
}
cursor.close();
db.close();
}
#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;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
InputContract.java
public class InputContract {
public static final String DB_NAME = "com.example.db";
public static final int DB_VERSION = 1;
public class TaskEntry implements BaseColumns {
public static final String TABLE = "tasks";
public static final String COL_TASK_TITLE = "title";
}
}
My Database:
InputDbHelper.java
public class InputDbHelper extends SQLiteOpenHelper {
public InputDbHelper(Context context) {
super(context, InputContract.DB_NAME, null, InputContract.DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + InputContract.TaskEntry.TABLE + " ( " +
InputContract.TaskEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
InputContract.TaskEntry.COL_TASK_TITLE + " TEXT NOT NULL);";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + InputContract.TaskEntry.TABLE);
onCreate(db);
}
}
By doing this:
db.delete(InputContract.TaskEntry.TABLE,
InputContract.TaskEntry._ID + " = ?", new String[] {
String.valueOf(positionToRemove)
}
);
you're coding it to use the position of the ListView item as a table ID, which it may work for the first rows when you create a new table, but when you'll start deleting items all things will get messed up.
You'll have to store the ID's either by creating a custom class for ArrayAdapter or by storing row ID to an Array/List and use positionToRemove to get the ID from that List, but that it can result to unexpected behaviur if you mess with the ListView and don't update the List data.
Check this question Custom Adapter for List View to see how you can create a custom adapter and save row ID to all ListView items along with the text.

how to update the list view after deletion data from list?

i am new to android.There is a listView in my application in which there is a list of questions and i want to update that list dynamically when i delete any question from it.please help.
public class admin extends Activity {
static int itemPosition;
ListView lv;
List<Question> quesList2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.admin);
lv=(ListView) findViewById(R.id.listView);
QuizHelper db = new QuizHelper(this); // my question bank class
quesList2 = db.getAllQuestions2();
int a= quesList2.size();
String[] testArray = new String[a];
for (int i = 0; i < testArray.length; i++) {
testArray[i]=quesList2.get(i).getQUESTION();
}
ArrayAdapter adapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1,
android.R.id.text1,testArray);
// Assign adapter to ListView
lv.setAdapter(adapter);
registerForContextMenu(lv);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
// TODO Auto-generated method stub
itemPosition = position;
}
});
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, v.getId(), 0, "Delete");//groupId, itemId, order, title
}
#Override
public boolean onContextItemSelected(MenuItem item){
QuizHelper db = new QuizHelper(this);
if(item.getTitle()=="Delete"){
db.deleteDB();
Toast.makeText(this, "Successfully deleted",
Toast.LENGTH_LONG).show();
lv.invalidateViews();
}
else{
return false;
}
return true;
}
}
here is the delete function which is in the databasehelper.java class.
protected void deleteDB(){
dbase = this.getWritableDatabase();
dbase.execSQL("DELETE FROM " + TABLE_QUEST + " WHERE " + KEY_ID + " =
'"+admin.itemPosition+"'");
}
You should use notifyDataSetChanged()
Notifies the attached observers that the underlying data has been
changed and any View reflecting the data set should refresh itself.
Code
if(item.getTitle()=="Delete"){
db.deleteDB();
adapter.notifyDataSetChanged();
}
You can get away with adapter.notifyDataSetChanged but this doesn't make sure that your data is actually deleted! there might be error while having database operation!
A cleaner approach will be setting a custom listener and notify the view from database class that it was a successful operation.
Create a interface,
public interface DatabaseListener {
void deleteSuccess();
void deleteError();
}
Assign listener to be notified,
public class admin extends Activity implements DatabaseListener{
...your codes
//you need to implement the interface methods
#Override
public void deleteSuccess(){
adapter.notifyDataSetChanged();
Toast.makeText(this, "Successfully deleted",Toast.LENGTH_LONG).show();
}
#Override
public void deleteError(){
Toast.makeText(this, "Failed to delete",Toast.LENGTH_LONG).show();
}
}
Notify listener,
protected void deleteDB(){
dbase = this.getWritableDatabase();
try {
dbase.execSQL("DELETE FROM " + TABLE_QUEST + " WHERE " + KEY_ID + " ='"+admin.itemPosition+"'");
//verify if the data is deleted
//get the databaseListener object from your Database class constructor.
databaseListener.deleteSuccess();
}catch(Exception e){
databaseListener.deleteError();
}
}
wherever you are calling the
deleteDB()
method, call
adapter.notifyDataSetChanged()
after that
Please consider to use recyclerview instead of list view.
here is a fantastic guide if you don't know how to use it: https://guides.codepath.com/android/using-the-recyclerview

Android - deleting items from ListView but not from Database

So I have a small problem, my code deletes ListView row from ListView but every time I kill the app and then reopen it the "deleted" rows populate the ListView again.
Here's the code for delete method in DatabaseHelper class:
public void obrisiTrening(int id){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(DBKonstante.TABLE_NAME, DBKonstante.KEY_ID + "=?", new String[]{String.valueOf(id)});
db.close();
And here's what my code for deleting ListView row and record from database:
rec_WorkoutItemsList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, final int i, long l) {
final Dialog dialog = new Dialog(MainActivity.this);
dialog.setContentView(R.layout.dialog_delete);
final TextView tvDialogDelete = (TextView) dialog.findViewById(R.id.tvDialogDelete);
tvDialogDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final DBPodatci infoData = dbPodatci.get(i);
dba = new DBHandler(MainActivity.this);
int position = dbPodatci.indexOf(infoData);
dbPodatci.remove(position);
DBPodatci podatki = new DBPodatci();
final int idToDelete = podatki.getItemId();
dba.obrisiTrening(idToDelete);
dba = new DBHandler(MainActivity.this);
dba.obrisiTrening(i);
rec_WorkoutItemsList.setAdapter(vjezbaAdapter);
vjezbaAdapter.notifyDataSetChanged();
dialog.dismiss();
}
});
dialog.show();
return false;
}
});
DB PODATCI
public class DBPodatci {
public String odabraneVjezbe, recordDate;
public int itemId;
public String getOdabraneVjezbe() {
return odabraneVjezbe;
}
public void setOdabraneVjezbe(String odabraneVjezbe) {
this.odabraneVjezbe = odabraneVjezbe;
}
public String getRecordDate() {
return recordDate;
}
public void setRecordDate(String recordDate) {
this.recordDate = recordDate;
}
public int getItemId() {
return itemId;
}
public void setItemId(int itemId) {
this.itemId = itemId;
}
}
Not sure what this is trying to do.
dba.obrisiTrening(idToDelete);
dba = new DBHandler(MainActivity.this);
dba.obrisiTrening(i);
You only need this
final TextView tvDialogDelete = (TextView) dialog.findViewById(R.id.tvDialogDelete);
final DBHandler dba = new DBHandler(MainActivity.this);
tvDialogDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final DBPodatci infoData = dbPodatci.get(i);
final int idToDelete = infoData.getItemId();
dbPodatci.remove(i);
dba.obrisiTrening(idToDelete);
vjezbaAdapter.notifyDataSetChanged();
dialog.dismiss();
And note: you shouldnt be using an Arraylist & ArrayAdapter here... You are using a database, so CursorAdapter is what you want

Saving Button's text in my listview which is connected to SQLite Database

I have a listview that have buttons in every row and is connected to my SQLite database.
Here's the code:
public class UpdateActivity extends Activity implements AdapterView.OnItemClickListener, View.OnClickListener {
ListView listView;
SimpleCursorAdapter dataAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
listView = (ListView)findViewById(R.id.listView1);
Appliances db = new Appliances(getApplicationContext());
Cursor cursor = db.getAllApp();
// The desired columns to be bound
String[] columns = new String[] { Appliances.KEY_APPNAME,Appliances.KEY_ONOFF };
// the XML defined views which the data will be bound to
int[] to = new int[] { R.id.text, R.id.right};
// create the adapter using the cursor pointing to the desired data
// as well as the layout information
dataAdapter = new SimpleCursorAdapter(this, R.layout.row_view,
cursor, columns, to, 0) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
View right = row.findViewById(R.id.right);
right.setTag(position);
right.setOnClickListener(UpdateActivity.this);
return row;
}
};
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(this);
EditText myFilter = (EditText) findViewById(R.id.myFilter);
myFilter.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
dataAdapter.getFilter().filter(s.toString());
}
});
dataAdapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
Appliances db = new Appliances(getApplicationContext());
return db.getAppliancesByName(constraint.toString());
}
});
}
public void onClick(View v) {
switch(v.getId()) {
case R.id.right:
Button tog = (Button)findViewById(R.id.right);
Appliances db = new Appliances(getApplicationContext());
Toast.makeText(this, "Right Accessory "+v.getTag(), Toast.LENGTH_SHORT).show();
Integer i = (Integer) v.getTag();
if(tog.getText().toString().equals("ON")){
//db.update_on(i, "ON");
tog.setText("OFF");
}else if(tog.getText().toString().equals("OFF")){
// db.update_on(i, "OFF");
tog.setText("ON");
}
break;
default:
break;
}
}
Whenever I click the Button in the second row in my listview, the button in the first row changes its text. In short, The if-condition is only applicable in the first row.
Every button must change its text into "ON" or "OFF" everytime I click them AND saves their texts in the SQLite database in their corresponding row.
Screenshot:
I may be entirely wrong ..but I strongly guess that it is because of Id.
Repalce this Code :
Button tog = (Button)findViewById(R.id.right);
With
Button tog = (Button)v
Becuase you have already assigned the id to that view and passed that to the onClick Method and When you reassign then it refers to the Button from your main layout.

Making ListView Items Clickable Trouble

My Listview gets information saved on a local database and displays the information. I am having altering what happens when my listview items are clicked. I want to delete them, can anybody assist me with this matter, while using my code? Thank you in Advance!
public class Notepad extends ListActivity {
public static final int INSERT_ID = Menu.FIRST;
EditText notes;
Button add;
ListView lv;
String currentDateTimeString = DateFormat.getDateInstance().format(
new Date());
private NotesDbAdapter mDbHelper;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.notepad_list);
mDbHelper = new NotesDbAdapter(this);
mDbHelper.open();
fillData();
Button add = (Button) findViewById(R.id.addNote);
// ListView lv = (ListView) findViewById(R.id.list);
add.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
createNote();
}
});
// lv.setOnItemClickListener(new OnItemClickListener() {
//
// public void onItemClick(AdapterView<?> parent, View view,
// int position, long id) {
// // When clicked, show a toast with the TextView text
//
// try {
// Toast.makeText(getApplicationContext(),
// ((TextView) view).getText(), Toast.LENGTH_SHORT)
// .show();
//
// } catch (ClassCastException e) {
// Toast.makeText(getApplicationContext(), "Error",
// Toast.LENGTH_SHORT).show();
// }
//
// };
//
// });
}
private void createNote() {
EditText notes = (EditText) findViewById(R.id.note);
String noteName = notes.getText().toString();
Calendar c = Calendar.getInstance();
int seconds = c.get(Calendar.SECOND);
int minutes = c.get(Calendar.MINUTE);
int hour = c.get(Calendar.HOUR);
mDbHelper.createNote(noteName + " Entered at " + hour + ":" + minutes
+ ":" + seconds, "");
fillData();
}
private void fillData() {
// Get all of the notes from the database and create the item list
Cursor c = mDbHelper.fetchAllNotes();
startManagingCursor(c);
String[] from = new String[] { NotesDbAdapter.KEY_TITLE };
int[] to = new int[] { R.id.text1 };
// Now create an array adapter and set it to display using our row
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.notes_row, c, from, to);
setListAdapter(notes);
}
}
My ListView:
<ListView
android:id="#id/android:list"
android:layout_width="wrap_content"
android:layout_height="402dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="#+id/note" >
</ListView>
onListItemClick you Got Position and Remove it from Dynamic Array (Vector or List) Like vector.remove(position);.if you want to remove it from Database ,Also remove from Database.After this You just write .....
adapter.notifyDataSetChanged();
What I do in my Apps, is override the SimpleCursorAdapter.setViewBinder() to set the Tag of Views inside the ListView with the ID (_ID) from the DB and delete this ID from the DB in the setOnItemClickListener() and refresh the Adapter. Something like this:
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.notes_row, c, from, to);
notes.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int column)
{
TextView tv = (TextView) view;
view.setTag=cursor.getInt(cursor.getColumnIndex ("_id")); // You need to include the _id in the query
tv.setText(String.Valueof(cursor.getInt(cursor.getColumnIndex (NotesDbAdapter.KEY_TITLE ))));
return true;
}
});
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
TextView tv=(TextView) view;
String ID=view.getTag();
// Delete ID from the DB
notes.notifyDataSetChanged();
};
});
setListAdapter(notes);
}
}
You an add an onItemClickListener on your ListView just as you added on the button.
If they click an item you delete that item in the local database using an sql query. I assume since you can select data you can delete it using SQL.
After that just reinitialize the list.
That's the easiest way:)
Although I think you could better use a longpress then a normal press.
Just that items won't be deleted by accident

Categories