I pass data from a ListView to another ListView with SharedPreference. I can write items and can remove an item of them.
After I delete item,I restart this page and I see item which I deleted. I cannot remove it permanently.
MainActivity
final DataProvider[] providers = gson.fromJson(jsonurun, DataProvider[].class);
final List<DataProvider> list = new ArrayList<>(Arrays.asList(providers));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
final DataProvider dataProvider = (DataProvider) adapterView.getItemAtPosition(i);
AlertDialog.Builder builder = new AlertDialog.Builder(Listele1.this);
builder.setMessage("Silinsin mi ?")
.setCancelable(false)
.setPositiveButton("EVET", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
list.remove(dataProvider);
prefAdapter.notifyDataSetChanged();
}
})
try change
prefAdapter.notifyDataSetChanged();
for notifyItemRemoved("here, position you has deleted");
notifyItemRangeChanged("here, position you has deleted" ,"your array".size());
When you are passing data form ListView 1 to ListView 2 using SharedPreference.
using below 2 lines.
final DataProvider[] providers = gson.fromJson(jsonurun, DataProvider[].class);
final List<DataProvider> list = new ArrayList<>(Arrays.asList(providers));
You only remove data from Listview 2 ie: list in your
case : list.remove(dataProvider);
And forgot to delete the data from SharedPreference at same time.That's why when restart the page your deleted item is visible again.
In short try to remove data form SharedPreference as well after performing
list.remove(dataProvider);
prefAdapter.notifyDataSetChanged();
Related
I am trying to create a waiter app which allows the waiter to take orders.
I am trying to achieve this using a ListView and setOnItemClickListener.
My idea is that every time a Item is clicked on the ListView it will be added to a ArrayList<Item>. Which later I can pass this List to a method created in DataBaseHelper which then iterates through the List and adds each Item from the order to the SQLite database.
I have not created the method in the DataBaseHelper class yet but I would like to know how to populate the ArrayList<Item> first and then move on to the next step.
The table I will be adding the list to has a manny to many relationship and is called order_item. Which also brings a question to mind as I do not need the full details about the Item and only the IDto save in the table do I need to get all the information of the Item?
Right now what is happening is the app allows me to click and add one Item and then the apps is forced to close.
I am also not sure if I should make the ArrayList a global variable or have it in the Order Object as a variable?
The log says:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131165292, class android.widget.ListView) with Adapter(class android.widget.ArrayAdapter)]
OrderActivity
public class OrderActivity extends AppCompatActivity {
EditText waiter_id;
Button order;
ListView orderList;
List<Item> itemList = new ArrayList<Item>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order);
waiter_id = (EditText) findViewById(R.id.waiter_id);
order = (Button) findViewById(R.id.order_button);
orderList = (ListView) findViewById(R.id.item_list);
//Showing Items on the ListView
DataBaseHelper dbHelp = new DataBaseHelper(OrderActivity.this);
final List<Item> itemList = dbHelp.getMenu();
ArrayAdapter itemArrayAdaptor = new ArrayAdapter<Item>(OrderActivity.this, android.R.layout.simple_list_item_1, itemList);
orderList.setAdapter(itemArrayAdaptor);
// setOnItemClickListener
orderList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
Item item;
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int pos, long id) {
//Selecting the Item and storing it in a reference variable to add to itemList
Toast.makeText(OrderActivity.this, "Order" + pos , Toast.LENGTH_SHORT).show();
Item item = (Item) adapterView.getAdapter().getItem(pos);
Toast.makeText(OrderActivity.this, item.toString() , Toast.LENGTH_SHORT).show();
itemList.add(item);
}
});
}
}
The problem was I was not notifying the list notifyDataSetChanged() that the item I selected had changed here is the code which now populates the list.
// setOnItemClickListener
orderList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
Order order;
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int pos, long id) {
//Selecting the Item and storing it in a reference variable to add to itemList
Toast.makeText(OrderActivity.this, "Order" + pos , Toast.LENGTH_SHORT).show();
orderItemList.add((Item) adapterView.getAdapter().getItem(pos));
itemArrayAdaptor.notifyDataSetChanged();
Toast.makeText(OrderActivity.this, orderItemList.toString(), Toast.LENGTH_SHORT).show();
}
});
orderList.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override public void onItemClick(AdapterView<?> adapterView, View
view, int pos, long id) {
Toast.makeText(OrderActivity.this, "Added"
,Toast.LENGTH_SHORT).show();
itemList.add(adapterView.getItemAtPosition(pos));
}
});
I have a simple RecyclerView for displaying items. Currently, from the RecyclerView.Adapter, I can delete items successfully using the following.
private void removeItem(int pos) {
filteredDataSet.remove(pos);
notifyItemRemoved(pos);
notifyItemRangeChanged(pos, getItemCount());
}
I call it from the onClick() function in the ViewHolder.The animations work, the view is updated, everything works. Pretty standard RecyclerView.
However, what I'd like to do is have the user verify the item deletion via a Dialog. Here's the basic setup for the Dialog (leaving out unnecessary code):
...
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.setTitle("Delete this item?");
builder.setView(layout);
final int itemPos = pos;
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
removeItem(itemPos);
}
});
...
So, I'm just moving the method call into the onClickListener of the Dialog.
The problem I'm having is that when the RecyclerView animates away the removed item, it animates it back in the exact same position, and the list stays the same. Like it's still there.
But, if I scroll down I get a out of bounds error:
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position
Which means it's not actually there, and when go back and come into the View again, it's gone. So, it seems like it's cached and not updating the adapter or dataset. I read that it needs called on the main thread, so I modified my method to this:
private void removeItem(int pos) {
final int itemPos = pos;
Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
#Override
public void run() {
filteredDataSet.remove(itemPos);
notifyItemRemoved(itemPos);
notifyItemRangeChanged(itemPos, getItemCount());
}
};
handler.post(runnable);
}
It's still not working, and I'm at a loss. I suspect it's a thread issue, but not sure where to turn from here.
This problem was solved by using a callback to trigger the removeItem() function when the item is deleted from the database. Apparently, adapter was being notified before the item was actually deleted from the database.
I'm using DBFlow to perform queries, so the solution is only applicable to DBFlow based solutions. This is called from the view that holds the RecyclerView:
public void deleteItem(int pos, long id) {
DatabaseDefinition database = FlowManager.getDatabase(AppDatabase.class);
//hold id to remove later
final long tempId = id;
final int tempPos = pos;
final ItemModel currentItem = getItem(id);
Transaction transaction = database.beginTransactionAsync(new ITransaction() {
#Override
public void execute(DatabaseWrapper databaseWrapper) {
currentItem.delete();
}
}).success(new Transaction.Success() {
#Override
public void onSuccess(Transaction transaction) {
mAdapter.removeItem(tempPos); //called here
}
}).error(new Transaction.Error() {
#Override
public void onError(Transaction transaction, Throwable error) {
Log.d("delete error", "item not deleted");
}
}).build();
transaction.execute();
}
if your removing from onClick from ViewHolder class then use getAdapterPosition() to get clicked location
if this code not working can you tell what is onItemClick() from your ViewHolder
In my code there is a listview in which i am doing an operation to delete the listview item. it works but remains displayed in the listview. It is in the second activity.It disappears only after going to the firstactivity and then returns.Please give me the changes that i have to make.
Getclicker.java
public void onItemClick(AdapterView<?> a, View v, int position, final long id) {
AlertDialog.Builder adb=new AlertDialog.Builder(Getclicker.this);
adb.setTitle("Delete?");
adb.setMessage("Are you sure you want to delete the event" + (position+1));
final int positionToRemove = position;
adb.setNegativeButton("Cancel", null);
adb.setPositiveButton("Ok", new AlertDialog.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
eventsData1.delete( id);
adapter.notifyDataSetChanged();
}});
adb.show();
}
delete method in database
public void delete(long id) {
SQLiteDatabase db = this.getReadableDatabase();
db.delete(DATABASE_TABLE, KEY_ROWID + " = ?",
new String[] { String.valueOf(id )});
db.close();
}
As I see, right now you're deleting an item from Database, but you're not deleting it from adapter, that's why deleted item is still in the ListView. When you go to another activity and then go back to the listView, you load changed data in the adapter.
You should delete an item from the adapter too if you want notifyDataSetChanged() to have an effect . . .
Your code should be something like this:
eventsData1.delete( id);
adapter.deleteItem(id);
adapter.notifyDataSetChanged();
add delete() method in your Adapter class . . .
You are deleting on the basis of id i.e Long Type
eventsData1.delete( id);
You should use "position"
eventsData1.delete(position);
adapter.notifyDataSetChanged();
As you mentioned your deleting operation is working fine but the problem is in listView refreshing. Untill and unless you are changing the activity it is not refreshing your list. What you have to really do is that you have to add this piece of code at the end of the line where deleting operation is ending within onItemClick:
yourListView.setAdapter(yourAdapter);
UPDATE
The original question i asked was about my long id value but because you guys were right in the way u said i had the correct id i removed my error. Thanks for the help. read my answer for more detail.
1) My app uses the local android SQLiteDatabase and has three tables. I have no problems for two of the tables but turns out my third one is presenting some issues because of my column declarations are public static final string COLUMN_NAME = "name"; ,etc.
My Activities are not extending the ListActivity so that I can have custom lists and listviews for each activity.
I am getting my listview by listview = (ListView) findViewById(R.id.myList); and adding a listener to the listview by listview.setOnItemClickListener(ListListener); Then here is my method for the list listener:
OnItemClickListener ListListener = new OnItemClickListener(){
public void onItemClick(AdapterView<?> arg0, View v, int position,
final long id)
{
AlertDialog.Builder dialog = new AlertDialog.Builder(ExerciseList.this)
.setIcon(R.drawable.edit)
.setTitle("Update Selected Exercise")
.setMessage("Would you like to update the current Exercise? Click continue to proceed.")
.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
final Intent i = new Intent(getBaseContext(), AddExercise.class);
i.putExtra(ExerciseDbAdapter.KEY_ROW_ID, id);
startActivityForResult(i, EDIT_EXERCISE);
}
})
.setNegativeButton("Back", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
dialog.show();
}
};
This above method is just a working on list item click listener!
Intent.putExtra("Key",value) is right way to put the data in intent so
i.putExtra("INSERT THE KEY HERE",ExerciseDbAdapter.KEY_ROW_ID, id);
Okay guys so i found the issue with my application and you were all right. I was getting the correct row id from the application.
I however was passing another data member through my intent causing the setRowIdFromIntent() method to change the id from null to 0. or from not null to 0.
Basically no matter what the value i was passing it was being set to 0 from my setRowIdFromIntent() method because of the data member i passed through. Therefore the above code is almost irrelevant to my problem.
So if you want a working on click list listener the one above will definitely help you pass the correct id to your new activity. Sorry again for this confusion I had on my side. Thanks again for all other postings!
So, i'm storing my datas in an IO-file! My datas are displayed and i want to delete an item from the listview, i maked this code, and i'm stucking!
L.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
final int arg2, long arg3) {
AlertDialog alert_reset;
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage("Supprimer cette donnée ?")
.setCancelable(false)
.setPositiveButton("Oui",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int id) {
.............
updatelv(activity);
}
})
.setNegativeButton("Non",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int id) {
dialog.cancel();
}
});
alert_reset = builder.create();
alert_reset.show();
return true;
}
Have i to use List.remove(arg2)?
And for deleting the data from a file, how can i do this ?
Thank you.
To remove an item from a ListView (which is just a display of some data) you need to remove the item from the data that backs the ListAdapter.
A common example is an Adapter that contains a list. To remove an item from the list and update the ListView you would do something like this.
myList.remove(arg2); // remove the item
myAdapter.notifyDataSetChanged(); // let the adapter know to update
IMHO the easiest way is to start by deleting the entry in the file, and then restart the "buildList" process. As the old entry is no more in the file, the new list won't show it any more.
About deleting in the file, it's more a java based question than Android, and it depends also on the store format you use (xml, json, custom ?). You should consider using a database, which is more flexible and easy to update.