Azoft / CarouselLayoutManager

Android Carousel LayoutManager for RecyclerView
Apache License 2.0
2.56k stars 367 forks source link

Buggy animation after adjusting PostLayoutListener #14

Closed JGreenwood94 closed 7 years ago

JGreenwood94 commented 8 years ago

Hi, after following the advice in the issue: https://github.com/Azoft/CarouselLayoutManager/issues/4 , and adjusting the zoom size and some of the spacing sizes and animation tends to jump around, especially when a carousel item settles at the centre point. Cheers

azoft-dev-team commented 8 years ago

Hi, could you please provide your code?

mig35 commented 8 years ago

@JGreenwood94 any update here?

nachtien commented 8 years ago

Hi @azoft-dev-team!

I'm experiencing a similar issue. I'm trying to fade all items that are not the center one away, after no interaction with the RecyclerView. I have it almost working, minus one bug. If you scroll really fast and then stop the scroll, the items fade as expected, but then appear right away. Do you have any suggestions?

Here's my code:

public class CarouselZoomPostLayoutListener implements CarouselLayoutManager.PostLayoutListener {

    @Override
    public ItemTransformation transformChild(@NonNull final View child, final float itemPositionToCenterDiff, final int orientation) {
        final float scale = (float) (2 * (2 * -StrictMath.atan(Math.abs(itemPositionToCenterDiff) + 1.0) / Math.PI + 1));

        // because scaling will make view smaller in its center, then we should move this item to the top or bottom to make it visible
        final float translateY;
        final float translateX;
        if (CarouselLayoutManager.VERTICAL == orientation) {
            final float translateYGeneral = child.getMeasuredHeight() * (1 - scale) / 2f;
            translateY = Math.signum(itemPositionToCenterDiff) * translateYGeneral;
            translateX = 0;
        } else {
            final float translateXGeneral = child.getMeasuredWidth() * (1 - scale) / 2f;
            translateX = Math.signum(itemPositionToCenterDiff) * translateXGeneral;
            translateY = 0;
        }

        if (itemPositionToCenterDiff == 0f) {
            child.clearAnimation();
            child.setAlpha(1f);
        } else {
            final Animation fadeOut = new AlphaAnimation(1, 0);
            fadeOut.setStartOffset(500);
            fadeOut.setDuration(500);
            fadeOut.setFillAfter(true);
            child.startAnimation(fadeOut);
        }
        return new ItemTransformation(scale, scale, translateX, translateY);
    }
}

Bonus question: How do I get how much the recyclerview has been scrolled? I currently just copied the source of the project into my app, and just made the "getMaxScrollOffset" public to do get it. Is there a better way?

Thanks in advance for your help.

mig35 commented 7 years ago

Hi @nachtien. Not sure if it late or not but.. I've checked your code and it is working fine except one thing: disappearing items if user stops his interaction. You need to change your code to start animation only if itemPositionToCenterDiff is near an integer value. That means that main item is near its center position. https://github.com/Azoft/CarouselLayoutManager/blob/master/resources/issues14.gif

nachtien commented 7 years ago

Thanks! There is a callback for when the view is detached from the recycler view which I used I stop the animations. It mitigated the problem significantly but it still exists On Thu, Nov 10, 2016 at 7:53 PM Mikhail Gurevich notifications@github.com wrote:

Hi @nachtien https://github.com/nachtien. Not sure if it late or not but.. I've checked your code and it is working fine except one thing: disappearing items if user stops his interaction. You need to change your code to start animation only if itemPositionToCenterDiff is near an integer value. That means that main item is near its center position.

https://github.com/Azoft/CarouselLayoutManager/blob/master/resources/issues14.gif

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Azoft/CarouselLayoutManager/issues/14#issuecomment-259875104, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHH9j7ThU9DyRsCSYrqN5mxrr5L9PO9ks5q8-abgaJpZM4JtD4t .

mig35 commented 7 years ago

@nachtien can you send a sample project to mig35 at mig35.com and make animation of your problem? I have same time to fix it. Thanks.

nachtien commented 7 years ago

Ok I'll try to do that by next week. Thanks! 🙏 On Thu, Nov 10, 2016 at 8:03 PM Mikhail Gurevich notifications@github.com wrote:

@nachtien https://github.com/nachtien can you send a sample project to mig35 at mig35.com and make animation of your problem? I have same time to fix it. Thanks.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Azoft/CarouselLayoutManager/issues/14#issuecomment-259876160, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHH9qQwFi7v_VUNtNd7aF00rEoUTmvDks5q8-kogaJpZM4JtD4t .

mig35 commented 7 years ago

@nachtien any update? :)

nachtien commented 7 years ago

@mig35, woops, thanks for following up with me. I've been so wrapped up with other works tasks that I had to put this to the side. I'll try to get this to you tomorrow. Thanks for following up with me again. 👍

mig35 commented 7 years ago

And again @nachtien :)

maxglu commented 7 years ago

Hi! I have the same issue with animation luggs after first start carousel. After i see all items, all works smooth, but first launch seems terrible.

nachtien commented 7 years ago

I'm gonna do this today @mig35!!

nachtien commented 7 years ago

Ughhhhhhh, work is hectic and I didn't get around it :(. We have another release coming up and I'm jam packed with things to do. The logic above with the CarouselZoomPostLayoutListener is what I currently have been using, and then in the reyclerview, when the view is detached, I stop the animations on the view.

nachtien commented 7 years ago

I really really appreciate you trying to help @mig35.

nachtien commented 7 years ago

You need to change your code to start animation only if itemPositionToCenterDiff is near an integer value. That means that main item is near its center position.

I actually did this too and the issue still happens.

mig35 commented 7 years ago

@nachtien could you post your code relative to this problem to my email? mig35 at mig35.com In my apps and layouts I cannot see any difficulties. The only way is to fully reproduce your layout and code in recyclerview holder (activity/fragment), adapter and etc. So this is why I need you code in project.

mig35 commented 7 years ago

@maxglu first launch and later things shouldn't be different a lot. Are you sure this is issue of carousel? Do you do any other work on the MainThread?

After i see all items, all works smooth, but first launch seems terrible. This sentence doesn't make sense carousel shows constant items count at the moment. And other elements are loaded from the recycler view using its cache, so there is no difference if you scroll it to see all the elements or not.

Please, post you animation somewhere or look through the previous post and send you buggy sample project to this email address.

mig35 commented 7 years ago

@maxglu I'll close this ticket because for @nachtien it was not carousel bug, but this was a bug in the custom PostLayoutListener. If you feel that this is our bug, you can start new issue and post your problem description. And I'll be glad to help you.

sagarhudge commented 5 years ago

@azoft-dev-team @JGreenwood94 @mig35 @nachtien @maxglu

On list scroll, view in center position jumps to its position my transition code is as follow view size is `90dp

     `final float scale = (float) (2 * (2 * -StrictMath.atan(Math.abs(itemPositionToCenterDiff) + 1.0) / Math.PI + 1));

    final float translateY;
    final float translateX;

    if (CarouselLayoutManager.VERTICAL == orientation) {

        final float translateYGeneral = child.getMeasuredHeight() * (1 - scale) / 2f;
        translateY = Math.signum(itemPositionToCenterDiff) * translateYGeneral;
        translateX = 0;

    } else {

        final float translateXGeneral = child.getMeasuredWidth() * (0.9f - scale) / 1.7f;
        translateX = Math.signum(itemPositionToCenterDiff) * translateXGeneral;
        translateY = 0;

    }

    return new ItemTransformation(scale, scale, translateX, translateY);`