Correctly animate removing row in ListView?

前端 未结 2 1303
有刺的猬
有刺的猬 2021-01-03 15:27

The problem:

(1) add a touch listener to rows in a listview so that on swipe.

(2) swipe animation plays

(3) rows get deleted in the backend, and

相关标签:
2条回答
  • 2021-01-03 15:45

    Chet Haase (Google Engineer) put together a really good DevBytes on this topic I'd suggest watching/taking ideas from his source. If you use NineOldAndroids, I think this'll be backwards compatible to GB.

    Check it out here:

    http://graphics-geek.blogspot.com/2013/06/devbytes-animating-listview-deletion.html

    0 讨论(0)
  • 2021-01-03 15:52

    As I pointed out in the comments, the problem with Chet's code is that its designed for synchronous data access. Once you start asynchronously deleting rows, his code fails.

    I found the solution to the flicker problem by combining Chet's code with this answer: CursorAdapter backed ListView delete animation "flickers" on delete

    The solution to correctly do a row deletion aynchronously is:

    1. Create a onPreDraw listener for the ListView tree observer to prevent flicker. All code in this listener runs before the list view re-draws itself, preventing flicker.
    2. Find a way to delete the row in the listview (but not yet in the database). There are two approaches (see CursorAdapter backed ListView delete animation "flickers" on delete):
      1. Create a AbstractCursor wrapper that ignores the row to be deleted and swap it in for the real cursor. OR
      2. Mark the row to be deleted as "stained" and act on it appropriately when redrawing the row.
    3. Remove the row for real in the database (asynchronously).

    Some pseudo-code using the AbstractCursor wrapper (it's technically called a "proxy"):

        //Called when you swipe a row to delete
        @Override
        public void onFling(final int positionToRemove, final View view)
        {
            final ViewTreeObserver observer = listView.getViewTreeObserver();
            observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
            {
                public boolean onPreDraw()
                {
                    observer.removeOnPreDrawListener(this);
    
                    //remove the row from the matrix cursor
                    CursorProxy newCursor = new CursorProxy(cursor,
                                                            positionToRemove);
                    swapCursor(newCursor);
                    //delete row in database
                 }
            }
      }
    
    0 讨论(0)
提交回复
热议问题