1

So, the title pretty much says it all. I have a listview which is populated with a custom cursor adapter which displays data from a database. I have an animation for adding items to the list which works fine but am having trouble getting the animation for deleting items from the list to work. I fear that the item is being deleted from the database and the list is being refreshed before the animation has a chance to execute. I appreciate any help with fixing this issue.

Animation code

    LayoutTransition transition = new LayoutTransition();
    Animator appearAnim = ObjectAnimator.ofFloat(null, "rotationX", 90f, 0f)
            .setDuration(android.R.integer.config_shortAnimTime);
    Animator disappearAnim = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f)
            .setDuration(android.R.integer.config_longAnimTime);
    transition.setAnimator(LayoutTransition.APPEARING, appearAnim);
    transition.setAnimator(LayoutTransition.DISAPPEARING, disappearAnim);
    mNotesListView.setLayoutTransition(transition);

The delete note method

 @Override
    public void deleteNote(final String noteId) {
        new Thread() {
            @Override
            public void run() {
                super.run();
                mNotesTable.deleteNote(mDb, noteId);
                int notebookNumber = mNoteBookFragment.getNotebookNumber();
                final Cursor cursor = mNotesTable.notesQuery(mDb, notebookNumber);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mNoteBookFragment.refreshNoteList(cursor);
                        Toast.makeText(BlocNotes.this,
                                getString(R.string.delete_note_toast), Toast.LENGTH_LONG).show();
                    }
                });
            }
    }.start();
}

and refreshing the list

public void refreshNoteList(Cursor cursor) {
        mNoteAdapter.changeCursor(cursor);
        mNoteAdapter.notifyDataSetChanged();

        setNewNoteText(""); //clear the text

    } 

Edited Refresh Method

 public void refreshNoteList(Cursor cursor) {
        mTransition.removeChild(mNoteAdapter.getParent(), mNoteAdapter.getView());
        mNoteAdapter.changeCursor(cursor);
        mNoteAdapter.notifyDataSetChanged();

        setNewNoteText(""); //clear the text

    }
Rich Luick
  • 2,354
  • 22
  • 35

1 Answers1

1

I've run into the same problem. You should call removeChild(parentView, childView) on Transition before you refresh the ListView. This might not be the best way, but it works.

I'd use a Loader here by the way: http://developer.android.com/guide/components/loaders.html

UPD: You need to run the rest of your code after the animation is finished (otherwise it will be interrupted). Something like this:

public void refreshNoteList(Cursor cursor) {
    transition.removeChild(ListView mNotesListView, View mNotesListView.getChildAt(int position);
    new Handler().postDelayed(new Runnable(){
        public void run() {
            mNoteAdapter.changeCursor(cursor);
            mNoteAdapter.notifyDataSetChanged();

            setNewNoteText(""); //clear the text
        }
    }, disappearAnim.getDuration());
}
Nikolai
  • 821
  • 3
  • 17
  • 22
  • Hey sorry, just came back to this after working on another project. It seems the Loader may be the best way to go so thank you. I will look into that in future projects. However, no dice on the removeChild method. Ill add my updated refresh method above but I simply just added transition as a member variable and added getters for view and parent in the adapter. I am not sure if this is correct so please let me know – Rich Luick Dec 23 '14 at 17:29
  • Okay so implementing this runnable essentially causes nothing to work in the app. It seems that it is not even running as the list is not updated when I add or delete something from it – Rich Luick Dec 29 '14 at 22:52
  • 1
    Hi! Sorry for the long silence. I'm a bit confused with this piece of code: `mTransition.removeChild(mNoteAdapter.getParent(), mNoteAdapter.getView());` You need to acquire a reference to your `ListView` instance and fetch its child view (the one you want to delete). You can also try to set the child's visibility to `View.GONE` and it will trigger the animation as well. – Nikolai Feb 08 '15 at 00:55