I used custom adapter for viewing listview. I tried to define my variables in adapter class but it didnt work. I find a temporary solution using invisible textview for this but i need to solve this problem. How can I overcome this?
Edit 1>
I have a column named date and this column contains datas like 20180723182036 and i grab this data to a list. I want to place this to listview as a variable and i will use this variable later.
My temporary solution is:
I have a code like that in database:
public ArrayList<SimpleNoteItem> getAllData() {
openDatabase();
ArrayList<SimpleNoteItem> newList = new ArrayList<>();
String[] columns = {KEY_ROWTITLE, KEY_ROWCONTENT, KEY_ROWDATE, KEY_ROWSTRDATE};
Cursor cs = db.query(DB_TABLE_NORMAL, columns, null, null, null, null, null);
while(cs.moveToNext()){
SimpleNoteItem allData = new SimpleNoteItem(cs.getString(0), cs.getString(1), cs.getLong(2), cs.getString(3));
newList.add(allData);
}
Collections.reverse(newList);
Log.d(LOGDB, "GETALLDATA STRUCTURE WORKS WELL!");
return newList;
}
Listview longclick constructor is this:
simpleNotesDisplay.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, final long id) {
Log.d(TAG, "LONG CLICKED " + position + " ITEM!");
//THIS AREA WILL BE EDITED FOR MORE ANDROID VERSION SUPPORT
AlertDialog.Builder builder;
final TextView getInvisibleDate = (TextView) view.findViewById(R.id.tv_date_invisible);
builder = new AlertDialog.Builder(NotesActivity.this, android.R.style.Theme_Material_Dialog_Alert);
builder.setTitle("Delete?")
.setMessage("Do you want to send this note to hell?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
db.deleteSimpleNote(getInvisibleDate.getText().toString());
Log.d(TAG, "DELETING SUCCESSFUL ON ID = " + id + "!!!");
NotesActivity.this.recreate();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//empty
}
})
.show();
return true;
}
});
}
And at least my invisible date:
<TextView
android:id="#+id/tv_date_invisible"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="TextView"
android:visibility="invisible"
tools:layout_editor_absoluteX="351dp"
tools:layout_editor_absoluteY="65dp" />
i hope it can help!
you should better to explain more about what you want but:
1)if you want to show some data in listview you most have a list of objects that each one has its data.
2)if you want to show different data in each row of listview then you most fill different data in each object of your list
3) if you want to show different view of each listviews row you most at first define different xml layouts and in your adapter where you define infelater you can use if else statment to decide which layout shows to witch row. below links will help you
Android ListView with different layouts for each row
https://www.javacodegeeks.com/2014/08/android-listview-with-multiple-row-layout.html
I found a different solution for that>>
I grab all data from database with this code:
public ArrayList<SimpleNoteItem> getAllData() {
openDatabase();
ArrayList<SimpleNoteItem> newList = new ArrayList<>();
String[] columns = {KEY_ROWTITLE, KEY_ROWCONTENT, KEY_ROWDATE, KEY_ROWSTRDATE};
Cursor cs = db.query(DB_TABLE_NORMAL, columns, null, null, null, null, null);
while(cs.moveToNext()){
SimpleNoteItem allData = new SimpleNoteItem(cs.getString(0), cs.getString(1), cs.getLong(2), cs.getString(3));
newList.add(allData);
}
Collections.reverse(newList);
Log.d(LOGDB, "GETALLDATA STRUCTURE WORKS WELL!");
return newList;
}
And in another activity i grab this list with this and then initialized it:
private ArrayList<SimpleNoteItem> getList = new ArrayList<>();
getList = db.getAllData();
initialize should be in onCreate method.
And then i used that data:
simpleNotesDisplay.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, final long id) {
Log.d(TAG, "LONG CLICKED " + position + " ITEM!");
//THIS AREA WILL BE EDITED FOR MORE ANDROID VERSION SUPPORT
AlertDialog.Builder builder;
builder = new AlertDialog.Builder(NotesActivity.this, android.R.style.Theme_Material_Dialog_Alert);
builder.setTitle("Delete?")
.setMessage("Do you want to send this note to hell?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
db.deleteSimpleNote(String.valueOf(getList.get(position).getSimpleNoteDate()));
Log.d(TAG, "DELETING SUCCESSFUL ON ID = " + id + "!!!");
NotesActivity.this.recreate();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//empty
}
})
.show();
return true;
}
});
Related
On deleting the item from the Listview the item gets deleted at that time, but on coming back to the activity the item reappears.
This is my Main2Activity code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
position = intent.getIntExtra("position", 0);
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listItem);
listView.setAdapter(adapter);
viewData1();
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int pos, long id) {
final int itemToDelete = pos;
new AlertDialog.Builder(Main2Activity.this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Are you sure?")
.setMessage("Do you want to delete this location?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
listItem.remove(itemToDelete);
databaseHelper1.deleteLocation(itemToDelete, position);
adapter.notifyDataSetChanged();
}
}
)
.setNegativeButton("No", null)
.show();
return true;
}
});
}
private void viewData1() {
Cursor cursor = databaseHelper1.viewData1(position);
if (cursor.getCount() == 0) {
Toast.makeText(this, "No data to show", Toast.LENGTH_SHORT).show();
} else {
while (cursor.moveToNext()) {
Log.i("message", "Data got");
listItem.add(cursor.getString(1));
}
adapter.notifyDataSetChanged();
}
}
DatabaseHelper:
public void deleteLocation(int itemToDelete,int position)
{
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
String itemDelete = Integer.toString(itemToDelete);
Log.i("itemdel",itemDelete);
if(position ==0)
{
String Id = (ID1);
Log.i("Id",Id);
String query = " Delete from "+DB_TABLE1 + " where "+ Id + " = " + itemDelete;
sqLiteDatabase.execSQL(query);
sqLiteDatabase.delete(DB_TABLE1,ID1 + " = "+ itemDelete, null);
sqLiteDatabase.compileStatement(query);
Log.i("del"," executed")
}
}
public Cursor viewData1(int position)
{
SQLiteDatabase sqLiteDatabase = this.getReadableDatabase();
Cursor cursor = null;
if (position ==0)
{
String query = "Select * from " + DB_TABLE1;
cursor = sqLiteDatabase.rawQuery(query, null);
}
return cursor;
}
What happens is:
Before Deleting:
After Deleting garden:
On restarting activity:
How do I commit the delete to the database? Thanks.
Your issue is that you are assuming that position (3rd parameter passed to the onItemLongClick method) directly relates to the id of the row.
You cannot rely on a correlation between position and id.
The first position in the list will be at position 0. The lowest ID allocated (unless forced) will be 1. However adding 1 is not a solution as even though it may initially work. As soon as you delete anything other than the last item in the list then an id is omitted from the list of id's and you may not delete a row or you may delete a different row.
The most sensible/easiest fix is to utilise a CursorAdapter i.e. SimpleCursorAdapter in which case the 4th parameter to onItemClick and onItemLongClick (long l) will be the actual id. However, to utilise a CursorAdapter you MUST have the id column named as _id (hence why there is the constant BaseColumns._ID).
You could always rename the column when extracting it using AS e.g. SELECT rowid AS _id, * FROM the_table; (which will select all existing columns AND the id column).
Here's a link to a more comprehensive answer with options for other adapter Deleting item from ListView and Database with OnItemClickListener
I have a ListView with some items and in each item there is a ImageButton for deleting this item.
The method for deleting the item is inside an ArrayAdapter which uses a view holder.
//ALERT DIALOG FOR DELETE
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Delete All?");
builder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which)
{
dialog.dismiss();
}
});
builder.setPositiveButton("Yes",
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
mHelper.deleteAll(gmid,true); //DELETE ITEM
remove(getItem(position)); //REMOVE ITEM FROM LIST
notifyDataSetChanged();
TextView txtGameCount = (TextView) ((Activity)getContext()).findViewById(R.id.txtGamesCount);
int GamesCount = mHelper.getGamesCount(tmid); //GET COUNT OF ITEMS
txtGameCount.setText(String.valueOf(GamesCount)); //SET TEXT WITH NEW NUMBER OF ITEMS
dialog.dismiss(); //CLOSE DIALOG
}
});
builder.show();
My problem is that the TextView for displaying the number of items is displaying "0" and not the actual count of items.
The count method is working while I am adding an item and it is the following:
public int getGamesCount(int id)
{
String countQuery = "SELECT * FROM " + TABLEG +" WHERE t_id="+ id +"";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
return cursor.getCount();
}
What I am doing wrong here?
thank you
You are using deleteAll() which will delete all records.
To delete a particular record use this function.
public void deleteRecords(String table, String whereClause,
String[] whereArgs) {
db.delete(table, whereClause, whereArgs);
}
Then there is no need to call
remove(getItem(position))
because
notifydatasetchange()
will reset the list again.
You have called deleteAll() and the n you are finding count so that will return 0 only because all records are deleted.
I create a listview in Android. My listview data is from sqlite database. When user click the item on the list. Alert dialog to delete confirmation will appear.
this is my code to delete from list:
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(todaycode.this);
alertDialog.setTitle("Delete from list");
alertDialog.setMessage("Are you sure to delete?");
final int del_position=position;
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,int which) {
//delete from database
mDb.deleteContact(list_food.get(+ del_position).getId());
//reload
final ArrayList<food_object> list_food = mDb.getAllfood();
final ListView list;
final String[] food_name = new String[list_food.size()];
for(int i=0;i<list_food.size();i++){
food_name[i]=list_food.get(i).getName();}
Integer[] imageId = {
R.drawable.image1,};
final customlist adapter = new customlist(todaycode.this, food_name, imageId);
list=(ListView)findViewById(R.id.listToday);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
});
and this is my code to delete from my database in DBAdapter:
public boolean deleteContact(int id)
{
return db.delete(TABLE_NAME, COL_ID + "=" + id, null) > 0;
}
this code is work. but sometimes user can't delete an item from the list until they reload this activity (move to other activity and back). The Alert dialog is appear, but after user click "Yes" there's nothing happen.
this only happen sometime. And only occure in one item on the list, so if user choose other item on the list to delete, it's still working. does anybody knows why this is happen?
EDITED
after many try, I conclude that the error (the item can't deleted) always started after user delete the second item (user deleting consecutively), and I'm still no idea why this is happen
this is my DBAdapter code, I simplified it See the Code
this is my customlist code See the Code
The problem is that you probably use autoincrement id in your table. When you get the id from the setOnItemClick it's actually the index of the item and not the id. So when you delete one at index 3 that id will be deleted and next time you want to delete at same index there won't be an item whit that id.
put this listener it will work then bro..!
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,int which) {
//delete from database
mDb.deleteContact(list_food.get(+ del_position).getId());
//reload
final ArrayList<food_object> list_food = mDb.getAllfood();
final ListView list;
final String[] food_name = new String[list_food.size()];
for(int i=0;i<list_food.size();i++){
food_name[i]=list_food.get(i).getName();}
Integer[] imageId = {
R.drawable.image1,};
final customlist adapter = new customlist(todaycode.this, food_name, imageId);
list=(ListView)findViewById(R.id.listToday);
list.setAdapter(null);
list.setAdapter(adapter);
}
});
I am building an application where I am using a ListView. Currently when the user clicks a row of the ListView, the following code executes. This code basically deletes some data concerned with the selected row. The code is a snippet from MainActivity.class.
//understanding this code is not crucial. list is the ListView, adapter is an
//ArrayAdapter object and displayDataMap is a Hashmap object.
list.setOnItemLongClickListener(new OnItemLongClickListener(){
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View view, int position, long id) {
String key = adapter.getItem(position); //position of ListView row
String data = displayDataMap.get(key);
displayDataMap.remove(key);
//"aqlpzaml" is used as a regex.
String addressee = data.split("aqlpzaml")[1];
long time = Long.valueOf(data.split("aqlpzaml")[0]);
int finalID = Integer.valueOf(data.split("aqlpzaml")[3]);
String dateTime = sdf.format(time);
adapter.remove(addressee + " " + dateTime);
adapter.notifyDataSetChanged();
}
Now I want that before deleting this data, the user is prompted with a Dialog, where he is asked if he is sure to make the changes.
I know how to create a Dialog and display it. But I don't know how to trigger change in the values of adapter and displayDataMap based on the Dialog input. I think if I'll use another class to create a Dialog object (using DialogFragment), then I won't be able to access the private variables of MainActivity class in the setPositiveButton() of that dialog.
Any suggestions ?
Thanks.
Just insert your Dialog creation in onItemLongClick and make the Adapter "adapter", "addressee" and "dateTime" final so you can access it in the setPositiveButton() method.
Cause i don't know how your Adapter is created it should look like this and in the same function as list.setOnItemLongClickListener or a class variable:
final ArrayAdapter<String> adapter = ...
also your datamap:
final Hashmap<String, ...> displayDataMap = ...
And your function should look like this:
list.setOnItemLongClickListener(new OnItemLongClickListener(){
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View view, int position, long id)
{
final String key = adapter.getItem(position); //position of ListView row
String data = displayDataMap.get(key);
//"aqlpzaml" is used as a regex.
final String addressee = data.split("aqlpzaml")[1];
long time = Long.valueOf(data.split("aqlpzaml")[0]);
int finalID = Integer.valueOf(data.split("aqlpzaml")[3]);
final String dateTime = sdf.format(time);
Builder dialog = new Builder(view.getContext());
dialog
.setMessage("Want to delete?")
.setPositiveButton("delete",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
displayDataMap.remove(key);
adapter.remove(addressee + " " + dateTime);
adapter.notifyDataSetChanged();
}
})
.setNegativeButton("cancel",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
dialog.cancel();
}
});
dialog.create().show();
}
}
I am building an application in which I'm populating data from the database into the listview of my activity. Now, on longItemClick Listener I want to delete that value from the database and update my listview in the app.
Here my code for longClickListener on the listview:
private ListView showing_history;
private ListAdapter mHistoryListAdapter;
private ArrayList<SearchHistoryDetails> searchArrayList;
private ArrayList<SearchHistoryDetails> HistoryObjArrayList;
mHistoryListAdapter = new ArrayAdapter<String>(this,
R.layout.mylistlayout, populateList());
showing_history.setAdapter(mHistoryListAdapter);
HistoryObjArrayList = new ArrayList<SearchHistoryDetails>();
/**
* Long tap on listview to delete the selected item from the history
* list.
* */
showing_history
.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0,
View arg1, int arg2, long arg3) {
final AlertDialog.Builder b = new AlertDialog.Builder(
MainActivity.this);
b.setIcon(android.R.drawable.ic_dialog_alert);
b.setMessage("Delete this from history?");
b.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
Toast.makeText(getApplicationContext(),
"Yes", Toast.LENGTH_LONG)
.show();
}
});
b.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
dialog.cancel();
}
});
b.show();
return true;
}
});
By this code I'm inserting data into the database:
/**
* Inserting the string when user searches for anything into the database.
* */
public void insertHistory(SearchHistoryDetails paraHistoryDetailsPojoObj) {
AndroidOpenDbHelper androidOpenDbHelperObj = new AndroidOpenDbHelper(
this);
SQLiteDatabase sqliteDatabase = androidOpenDbHelperObj
.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(AndroidOpenDbHelper.COLUMN_NAME_HISTORY_STRING,
paraHistoryDetailsPojoObj.getHistoryName());
#SuppressWarnings("unused")
long affectedColumnId = sqliteDatabase.insert(
AndroidOpenDbHelper.TABLE_NAME_HISTORY, null, contentValues);
sqliteDatabase.close();
}
Here is the code from which I'm retrieving data from the database and repopulating it into the list view:
public List<String> populateList() {
List<String> HistoryNamesList = new ArrayList<String>();
AndroidOpenDbHelper openHelperClass = new AndroidOpenDbHelper(this);
SQLiteDatabase sqliteDatabase = openHelperClass.getReadableDatabase();
Cursor cursor = sqliteDatabase
.query(AndroidOpenDbHelper.TABLE_NAME_HISTORY,
new String[] { AndroidOpenDbHelper.COLUMN_NAME_HISTORY_STRING },
null, null, null, null, AndroidOpenDbHelper.ID
+ " DESC");
startManagingCursor(cursor);
while (cursor.moveToNext()) {
String ugName = cursor
.getString(cursor
.getColumnIndex(AndroidOpenDbHelper.COLUMN_NAME_HISTORY_STRING));
SearchHistoryDetails histPojoClass = new SearchHistoryDetails();
histPojoClass.setHistoryName(ugName);
searchArrayList.add(histPojoClass);
HistoryNamesList.add(ugName);
}
sqliteDatabase.close();
int history_db = cursor.getCount();
if (history_db == 0) {
history_layout.setVisibility(LinearLayout.GONE);
} else {
history_layout.setVisibility(LinearLayout.VISIBLE);
}
return HistoryNamesList;
}
Retrieving and inserting data all things are perfectly, but deleting of a particular row is not working for me. Right now I have done some action using toast and it is working, what should I do so that, the database data updates after deletion of the row from the listview. Please give me any idea to overcome this problem.
Try this..,.
b.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
DatabaseHandler db=new DatabaseHandler(getApplicationContext());
db.delete(arg3+"");
list.remove(position);
YourActivity.this.adapter.notifyDataSetChanged();
}
});
and in DatabaseHandler class
public void delete(String id)
{
SQLiteDatabase db = this.getReadableDatabase();
db.delete(TABLE_NAME, KEY_ID + "=?", new String[]{id});
db.close();
}
most proper solution is to use Loaders.. especially CursorLoader along with Content Provider.
If Content Provider is an overkill for what you are doing try CursorLoader from commonsware. The update after deletion happens automatically and not in the ui thread which is good.
https://github.com/commonsguy/cwac-loaderex.. its pretty easy once you get your head around this.
However if you still want to delete the row as per your code. Just delete it in your longpress listener. But after that refresh the adapter.
How to refresh Android listview?
To update list.. Firstly call the method where you specified the delete query from builder positive button.
After that delete the item from HistoryNamesList array list
Now the data removed from both database and arraylist but listview still show previous data so you have to notify listview adapter as show below
adapter.notifyDataSetChanged();
adapter.notifyDataSetInvalidated();
Solved!
Changes made on onCLick():
public void onClick(DialogInterface dialog,
int whichButton) {
HistoryNamesList.remove(pos);
((BaseAdapter) mHistoryListAdapter)
.notifyDataSetChanged();
}