yuyakaido / CardStackView

πŸ“±Tinder like swipeable card view for Android
Apache License 2.0
2.37k stars 448 forks source link

First frame of rewind animation shows final animated state #251

Closed damien5314 closed 5 years ago

damien5314 commented 5 years ago

Hi, I'm observing a small UI glitch while trying out the CardStackView.rewind() API. It seems after calling rewind(), the previous card (i.e. the card that is about to be rewound into view) is shown where the current card is, before animation takes place to move the previous card on top of the current card.

It's best seen by checking a video in action: https://drive.google.com/file/d/1GQ7iPd0zrH36jJbOAHA_kEvlUydGKHq_/view?usp=sharing

frame 0 frame 1 frame 2 frame 3 frame 4
Screenshot 2019-05-14 11 04 04 Screenshot 2019-05-14 11 04 11 Screenshot 2019-05-14 11 04 16 Screenshot 2019-05-14 11 04 20 Screenshot 2019-05-14 11 04 23

Is the animator pushing the card into its final resting position on the first frame of the animation, then moving it down to its proper place? It's hard for me to tell πŸ˜“ Any help would be appreciated πŸ™‡

yueban commented 5 years ago

I've got the same problem and try to solve it for a while. Here's what I found:

1. how does the problem happen?

you can find this part of code in CardStackSmoothScroller:

if (type == ScrollType.AutomaticRewind) {
    manager.getCardStackState().scrollerStatus = CardStackState.ScrollerStatus.onSeekTargetStep;

    manager.removeAllViews();
    RewindAnimationSetting setting = manager.getCardStackSetting().rewindAnimationSetting;
    action.update(
            -getDx(setting),
            -getDy(setting),
            setting.getDuration(),
            setting.getInterpolator()
    );

it will remove all views and then use the scroller to start a scroll event. The scroll event make dx/dy changed and invoke scrollHorizontallyBy/scrollVerticallyBy function. Finally it jump into CardStackLayoutManager.update function and update child views.

the problem is, when it remove all views, the dx/dy is 0, so you see the topView at the original position on first frame. the it animate correctly cause the scroll event has began.

2. how to solve it?

I found a way to determine if it is the first frame of rewind animation which is the moment all view removed as we mentioned above.

you can check the implementation on the commit.

3. futhermore

this way to fix the problem is some kind like a hack. And the ideal way is not removing all views but just remove the bottom child and add back the topView which should be rewound. Hope someone can fix it.

yuyakaido commented 5 years ago

@damien5314 @yueban Thank you for your report! This issue has been fixed in ver. 2.3.4.

damien5314 commented 5 years ago

@yuyakaido Works wonderfully, thank you!