Skip to content
This repository was archived by the owner on Nov 21, 2024. It is now read-only.

Commit 3938ba6

Browse files
committed
Tweak onboarding topics animation and entry.
Change-Id: Ic50329534bf8e60e2912aca1c2c4ad32daddd79a
1 parent 8815c43 commit 3938ba6

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

app/src/main/java/com/materialstudies/owl/ui/onboarding/OnboardingFragment.kt

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@
1717
package com.materialstudies.owl.ui.onboarding
1818

1919
import android.os.Bundle
20+
import android.util.DisplayMetrics
2021
import android.view.LayoutInflater
2122
import android.view.View
2223
import android.view.ViewGroup
2324
import androidx.annotation.Px
2425
import androidx.core.view.forEach
25-
import androidx.core.view.postDelayed
2626
import androidx.dynamicanimation.animation.SpringAnimation
2727
import androidx.fragment.app.Fragment
2828
import androidx.navigation.fragment.findNavController
29+
import androidx.recyclerview.widget.LinearSmoothScroller
2930
import androidx.recyclerview.widget.RecyclerView
3031
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING
3132
import com.materialstudies.owl.R
@@ -53,7 +54,7 @@ class OnboardingFragment : Fragment() {
5354
// data ordered LTR, so reverse it before setting
5455
submitList(topics.reversed())
5556
}
56-
smoothScrollToPosition(topics.size)
57+
smoothScrollToPositionWithSpeed(topics.size)
5758
addOnScrollListener(
5859
OscillatingScrollListener(resources.getDimensionPixelSize(R.dimen.grid_2))
5960
)
@@ -67,14 +68,18 @@ class OnboardingFragment : Fragment() {
6768
* Oscillates a [RecyclerView]'s children based on the horizontal scroll velocity.
6869
*/
6970
private const val MAX_OSCILLATION_ANGLE = 6f // ±6º
71+
7072
class OscillatingScrollListener(
7173
@Px private val scrollDistance: Int
7274
) : RecyclerView.OnScrollListener() {
7375
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
7476
// Calculate a rotation to set from the horizontal scroll
75-
val rotation =
76-
(dx.coerceIn(-scrollDistance, scrollDistance) / scrollDistance) * MAX_OSCILLATION_ANGLE
77+
val clampedDx = dx.coerceIn(-scrollDistance, scrollDistance)
78+
val rotation = (clampedDx / scrollDistance) * MAX_OSCILLATION_ANGLE
7779
recyclerView.forEach {
80+
// Alter the pivot point based on scroll direction to make motion look more natural
81+
it.pivotX = it.width / 2f + clampedDx / 3f
82+
it.pivotY = it.height / 3f
7883
it.spring(SpringAnimation.ROTATION).animateToFinalPosition(rotation)
7984
}
8085
}
@@ -87,3 +92,17 @@ class OscillatingScrollListener(
8792
}
8893
}
8994
}
95+
96+
fun RecyclerView.smoothScrollToPositionWithSpeed(
97+
position: Int,
98+
millisPerInch: Float = 100f
99+
) {
100+
val lm = requireNotNull(layoutManager)
101+
val scroller = object : LinearSmoothScroller(context) {
102+
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float {
103+
return millisPerInch / displayMetrics.densityDpi
104+
}
105+
}
106+
scroller.targetPosition = position
107+
lm.startSmoothScroll(scroller)
108+
}

0 commit comments

Comments
 (0)