Search code examples
androidandroid-listviewandroid-animationandroid-arrayadapter

android listview deletion animation is automatically deleting a second item


I have a list view with a custom adapter. Each item has a delete icon which prompts a delete dialog fragment. on deleting the item, I am performing a slide animation and on animation end. the item is deleted from the list and adapter is notified about the deletion like below:

// dialog fragment on clicking "delete"
positive.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final FoldingCell fView = (FoldingCell) thisItem.getParent().getParent();

// wait for fold to finish then delete item
                fView.postDelayed(new Runnable() {
                    @Override
                    public void run() {

                        deleteCell(fView, pos);

                    }
                }, 850);

my adapter is of type FoldingCell so I am folding back the cell before deletion, hence the postDelayed. The deleteCell is the simple animation below:

private void deleteCell(final View v, final int index) {

    TranslateAnimation transanim = new TranslateAnimation(0, 800, 0, 0);
    transanim.setDuration(700);

    transanim.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            items.remove(index);

            // update array adapter
            adapter.notifyDataSetChanged();
            v.setVisibility(View.GONE);

        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    });
    v.startAnimation(transanim);
}

An important not is that I also am using stableIds which might be causing the problem. After the animation deletion occurs, the adapter is deleting two items instead of just the one clicked on. when I disable the animation in the above code, and just write

    items.remove(index);
    adapter.notifyDataSetChanged();

exactly on delete, the deletion works perfectly even with stable ids (there is just no animation) why is that? The problem seems like its a combination of the animation and stable ids, since if stableids is false, the deletion works with the animation.

I cannot find a good solution for this other than making stable ids false and solve other issues that arise from doing that.


Solution

  • Solved! The reason why with stableids the adapter was deleting an extra fields was that when I override getItemId, I was returning the adapter position itself which, I guess, during the animation when an item is deleted, that same position id is taken by another list item which gets deleted as well. By returning a different itemId that is unique to the list item, this error does not occur. so I changed this:

    @Override
        public long getItemId(int position) {
            return position;
        }
    

    to this:

    @Override
    
    public long getItemId(int position) {
        Item item = items(position);
        return item.getId();
    }
    

    where items is the arraylist I am passing to the adapter. Item is my class that holds the elements/views of each item and getId() is the getter I have to return the id integer of each Item