Remove Items from Listview With a Custom Adapter

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



Leave a reply



Submit