Delete items from custom adapter android
Your problem might be here
@Override
public void remove(String s) {
verifySelectedItems(getPosition(s));
super.remove(s);
notifyDataSetChanged();
}
You remove the item from the adapter, but not the index from checkedItems
If i were you, instead of keeping a boolean array to keep track of checked items, I would use an ArrayList<Integer>
and keep all of the checked positions in the list.
You could then change that method to look something like this
@Override
public void remove(String s) {
int pos = getPosition(s);
verifySelectedItems(pos);
remove(s);
checkedItems.remove(Integer.valueOf(pos));
notifyDataSetChanged();
}
And then this...
private void verifySelectedItems(int position) {
checkedItems[position] = false;
for (boolean checked : checkedItems) {
if (checked)
return;
}
activityCallback.hideContent();
}
could instead be this
private void verifySelectedItems(int position) {
if(!checkedItems.contains(position)) {
activityCallback.hideContent();
}
}
EDIT:
Sorry I didn't read the question properly, I think this is your problem
if (row == null) {
row = mInflater.inflate(R.layout.list_view_row_song, null);
holder = new Holder();
holder.text = (TextView) row.findViewById(R.id.tvFileName);
holder.configs = (TextView) row.findViewById(R.id.tvFileConfiguration);
holder.checkBox = (CheckBox) row.findViewById(R.id.cbDelete);
holder.playButton = (ImageButton) row.findViewById(R.id.btnPlay);
holder.settingsButton = (ImageButton) row.findViewById(R.id.btnSettings);
holder.text.setText(getItem(position));
holder.configs.setText(getLyricConfiguration(getItem(position)));
row.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
You are removing the correct items, but this prevents the views from being updated after a notifydatasetchanged, maybe try something like this
if(convertView == null) {
convertView = mInflater.inflate(R.layout.list_view_row_song, null);
}
Holder holder = new Holder();
holder.text = (TextView) convertView.findViewById(R.id.tvFileName);
holder.configs = (TextView) convertView.findViewById(R.id.tvFileConfiguration);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.cbDelete);
holder.playButton = (ImageButton) convertView.findViewById(R.id.btnPlay);
holder.settingsButton = (ImageButton) convertView.findViewById(R.id.btnSettings);
holder.text.setText(getItem(position));
holder.configs.setText(getLyricConfiguration(getItem(position)));
Removing an item from ListView inside a custom adapter
Try this
@Override
public View getView(final int pos, View convertView, ViewGroup parent) {
View v = convertView;
// Some other things...
ImageButton removeFav = (ImageButton) v.findViewById(R.id.removeFavorites);
removeFav.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// After you delete the object from Parse database here,
notifyDataSetChanged();
}
}
How to delete item from ListView while using Custom ArrayAdapter w/ Dialog
You can do this in either way . You can create a function in your adapter class and perform the clickListener on it .
deleteItem.setOnClickListener(v -> {
potsList.remove(getAdapterPosition());
notifyDataSetChanged();
}
Or in your class , when remove the item from list , don't forget to notify the adapter . One the adapter get notified , it will reflect the change on screen.
ListView custom adapter, remove item using AsyncTask
before you call mAdapter.notifyDataSetChanged();
you should remove the element from mAdapter.
delete item from custom listview
I am posting code for deleting item from listview which is working correctly in my code.
You forgot to call notifysetchanged thats it.
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row = null;
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.one_result_details_row, parent, false);
// inflate other items here :
Button deleteButton = (Button) row.findViewById(R.id.Details_Button01);
deleteButton.setTag(position);
deleteButton.setOnClickListener(
new Button.OnClickListener() {
@Override
public void onClick(View v) {
Integer index = (Integer) view.getTag();
items.remove(index.intValue());
notifyDataSetChanged();
}
}
);
plz have a look at the following answers
1) Remove ListView items in Android
2) Remove selected item from ListView
Let me know if you are still facing any issue...
Thanks
ListView using custom Adapter. Button to remove a child in a Firebase Database
Your question is sort of a mini-project, but I made some code for you that hopefully helps.
The code below makes a sample arraylist of "thingy" objects. A Thingy object has a name (eg: box,toy,cat) and UID field (produced using the push() method you mentioned you're using). The list of Thingy objects are then set to the FirebaseDatabase root node (ref) with their labels being their UID. While you probably have this code written, we'll use this code block as an example.
// a root database reference
DatabaseReference ref =
FirebaseDatabase.getInstance().getReference().child("RootNode");
// sample arraylist of objects
// Thingy objects have a type and UID field
ArrayList<Thingy> thingyList = new ArrayList();
thingyList.add(new Thingy("box",ref.push().getKey()));
thingyList.add(new Thingy("toy",ref.push().getKey()));
thingyList.add(new Thingy("cat",ref.push().getKey()));
// set all Thingy objects in thingyList to your root node
// under the label that is the thingy's UID
for (Thingy x : thingyList) {
ref.child(x.getUID()).setValue(x);
}
// setup the adapter and listview
// R.id.remove_item is an xml layout that contains
// a textview and a remove button
MyAdapter myAdapter = new MyAdapter( this, R.layout.remove_item, thingyList);
ListView myList = (ListView) findViewById(R.id.removeListView);
myList.setAdapter(myAdapter);
Then in order to use your adapter to use remove buttons to delete the thingy objects from your FirebaseDatabase, you can attach an onClickListener to each Button for every item. Then use remove() to fully delete the object from the database.
public class MyAdapter extends ArrayAdapter<ArrayList> {
private Context context;
private int resource;
private ArrayList arrayList;
private DatabaseReference ref =
FirebaseDatabase.getInstance().getReference().child("RootNode");
public MyAdapter(Context context, int resource, ArrayList arrayList) {
super(context, resource, arrayList);
this.context = context;
this.resource = resource;
this.arrayList = arrayList;
}
private static class ViewHolder {
TextView type;
Button removeButton;
}
@Override
public View getView(int position, View convertView,ViewGroup parent) {
View row;
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(resource, parent, false);
viewHolder.type = (TextView) row.findViewById(R.id.type);
viewHolder.removeButton = (Button) row.findViewById(R.id.removeButton);
row.setTag(viewHolder);
} else {
row = convertView;
viewHolder = (ViewHolder) convertView.getTag();
}
final Thingy x = (Thingy) arrayList.get(position);
viewHolder.type.setText(x.getType());
viewHolder.removeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ref.child(x.getUID()).removeValue();
}
});
return row;
}
Attaching a listener to every item can be expensive, so if you have a large list of objects, performance may drop. However, this is the implementation for using a listener in the adapter, and working with adapters can become tricky when your listview items become more complicated. So maybe as you learn more and more android, you can find a more efficient way of removing items in your project.
As for your other questions:
Yes, onChildRemoved will be called. However, it doesnt make sense to update listviews from onChildRemoved. If a user deletes an item, onClick should do the deleting. As for other users who access the same database, they should simply read the database at the time their app tries to create the listview. Using onChildRemoved makes sense only if you need to broadcast some type of alert to all other users that something has happened.
Using push() is an easy and safe way to create unique id's (UID in my code) that can be used to reference objects throughout your project. While you can use inheritance to separate objects from their UID's (have a parent class that only holds id's and use setValue on the child class object), I very often just include the UID in the objects instance fields and then get the UID when sending them to the database.
Related Topics
Download a File Programmatically on Android
How to Get Last Record from Sqlite
Update Some Specific Field of an Entity in Android Room
Adb Is Not Detecting My Android Device on Ubuntu
How to Remove Focus Without Setting Focus to Another Control
Download Manager Progress Not Visible in the Notification Area
Access Denied Finding Property "Camera.Hal1.Packagelist"
Android Studio 0.4.3 - Task 'Assemble' Not Found in Root Project
How to Make a Background 20% Transparent on Android
Android Shared Preferences For Creating One Time Activity (Example)
Android - Transform Classes With Dex for Debug
Adb.Exe Not Found After Installing Android Studio
Touchableopacity Not Working Inside an Absolute Positioned View
How to Prevent User Go Back to Protected Page After Logout
How to Set the Starting Position of a Scrollview