Azoft / CarouselLayoutManager

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

Jumping feel while sliding slowly #23

Open iamshajeer opened 7 years ago

iamshajeer commented 7 years ago

Hi, When I scroll from one card to another very slowly it jumps from on to another. the scrolling is not smooth, I think you are bringing the next card immediately. can you make it pixel by pixel ? also is there any way that I can adjust the position of cards ?

mig35 commented 7 years ago

@iamshajeer What do you mean by "scrolling is not smooth" and "make it pixel by pixel"? This is carousel layout. Don't understand what do you want to adjust. Can you make a picture?

iamshajeer commented 7 years ago

Thanks for your concern. Issue is when you try to change(scroll) one recyclerview item to another the second item comes suddenly. Which is not smooth. May be I can create a gif and post very soon. Also is there any way to change the bottom position of the next and previous items ? I couldn't find anything. Please clarify.

mig35 commented 7 years ago

@iamshajeer Bottom and zoom of the next and previous items are controlled by CarouselZoomPostLayoutListener. Check its code. There are come Mathematics functions of zooming and positioning.

About not smooth animation.. not sure how you want it to look like.

mig35 commented 7 years ago

@iamshajeer any update here? can you give me an example of such animation?

nachtien commented 7 years ago

@mig35, I think he's talking about something like this, where the items should be going smoothly, similar to just a standard horizontal layout manager, but with all the utility methods that you guys provide (which is what I'm trying to figure out right now).

scrolling

mig35 commented 7 years ago

Hi @nachtien as I can see all that we need to change is a Math algorithm in PostLayoutListener. We provide only one variant with zoom and translate logic in CarouselLayoutManager/CarouselLayoutManager/carousel/src/main/java/com/azoft/carousellayoutmanager/CarouselZoomPostLayoutListener.java but anyone can build there own PostLayoutListener.

roman-inmanage commented 7 years ago

Hey! If I understand right your issue so try to change this line in CarouselZoomPostLayoutListener: final float translateXGeneral = child.getMeasuredWidth() * (1 - scale) / 2f;

to this one: final float translateXGeneral = child.getMeasuredWidth() * (1 - scale) / 0.8f;

I use horizontal carousel and it's make the animation looks better and child views not overlapping centered view

roman-inmanage commented 7 years ago

In addition to my previous answer you can change this line in CenterScrollListener: recyclerView.smoothScrollBy(scrollNeeded, 0);

to this one: recyclerView.smoothScrollBy(scrollNeeded, 0, new DecelerateInterpolator());

This one will slow down the animation on centered view and it will look better

AnkitDApalya commented 7 years ago

Hi, I have the somewhat same issue, Centre Image try to relocate to middle with a jerk, even it is calling recyclerView.smoothScrollBy(scrollNeeded, 0); in CenterScrollListener file.

kristynarehovicova commented 7 years ago

Hi, the same here. Sometimes it scrolls smooth, sometime it "jumps" from one recycler item to another.

galisamas commented 7 years ago

Hi, same here. I'm dealing the same issue with jumps. When scrolling second element to the centre position and sizes of the centre and the second elements becomes the same, second element just jumps to the centre position. When itemSelectedListener works with UI or when adapter is loading images with Glide it starts jumping.

red742652 commented 7 years ago

Hi everybody, Just remove calculateScrollForSelectingPosition() method call in CarouselLayoutManager can get rid of the jumping feel. Line 361,365 and 368. I don't know whether this method is useful in other case, In my case,this method is unnecessary and cause the item jump to the center position while scrolling.

jpvs0101 commented 6 years ago

@red742652 Don't do that! It will cause problem when add, remove items! refer this

mig35 commented 6 years ago

Hi @jpvs0101

I don't want to remove calculateScrollForSelectingPosition method call because of this problem, but want to find a bug in jumping...

And thanks for your help and really active position!

sagarhudge commented 5 years ago

@mig35 @iamshajeer @nachtien @roman-inmanage @AnkitDApalya any update on this issue I am facing same

asadmukhtar28 commented 5 years ago

where is the complete code for removing that jumpy jerk, kindly i need it.

JeneaVranceanu commented 3 years ago

For all of those who are still interested in a solution.

First of all, there is no need to modify the source code! As @mig35 stated:

as I can see all that we need to change is a Math algorithm in PostLayoutListener.

Absolutely correct!

What was causing the jerking/jumping movement is the scale calculation. I created an implementation of PostLayoutListener based on the one provided with the library (CarouselZoomPostLayoutListener) and replaced the calculation of scale.

In my case, it was calculated as simple as: val scale = 1f - 0.17f * abs(itemPositionToCenterDiff) Where 0.17f is the value that tells in percentage how small next item will be relative to the previous one.

It works this way: the centre item is scaled 1:1 items to left and right of it will be 17% smaller; the next item to the left and right will be 34% smaller and so on.

Here is the full implementation in Kotlin of PostLayoutListener.

/**
 * [PostLayoutListener] implementation used to translate and scale views.
 *
 * @param scaleMultiplier value used to scale items that move closer to the center or away from it.
 * Centered item is presented in its original size (scaled as 1:1).
 * Pass positive value to reduce item size relative to the centered one, negative to increase (centered item is always 1:1).
 */
class PostsCarouselZoomPostLayoutListener(private val scaleMultiplier: Float = 0.17f) : PostLayoutListener {
    override fun transformChild(
        @NonNull child: View,
        itemPositionToCenterDiff: Float,
        orientation: Int
    ): ItemTransformation {
        val scale = 1f - scaleMultiplier * abs(itemPositionToCenterDiff)

        // because scaling will make view smaller in its center, then we should move this item to the top or bottom to make it visible
        val translateY: Float
        val translateX: Float
        if (CarouselLayoutManager.VERTICAL == orientation) {
            val translateYGeneral = child.measuredHeight * (1 - scale) / 2f
            translateY = Math.signum(itemPositionToCenterDiff) * translateYGeneral
            translateX = 0f
        } else {
            val translateXGeneral = child.measuredWidth * (1 - scale) / 2f
            translateX = Math.signum(itemPositionToCenterDiff) * translateXGeneral
            translateY = 0f
        }
        return ItemTransformation(scale, scale, translateX, translateY)
    }
}
mig35 commented 3 years ago

Great thing @JeneaVranceanu . I'm going to test your code and perhaps will add it as an other PostLayoutListener