Skip to content

Commit

Permalink
Implement faster quadratic speed scrolling
Browse files Browse the repository at this point in the history
  • Loading branch information
meenbeese authored and Iamlooker committed Aug 7, 2024
1 parent 099f944 commit 0df58af
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.looker.core.common.Scroller
import com.looker.core.common.R as CommonR
import com.looker.core.common.R.string as stringRes
import com.looker.core.common.extension.dp
Expand Down Expand Up @@ -104,7 +105,11 @@ class AppListFragment() : Fragment(), CursorOwner.Callback {
} else {
text = ""
setIconResource(CommonR.drawable.arrow_up)
setOnClickListener { recyclerView.smoothScrollToPosition(0) }
setOnClickListener {
val scroller = Scroller(requireContext())
scroller.targetPosition = 0
recyclerView.layoutManager?.startSmoothScroll(scroller)
}
alpha = 0f
isVisible = true
systemBarsMargin(16.dp)
Expand Down
54 changes: 54 additions & 0 deletions core/common/src/main/java/com/looker/core/common/Scroller.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.looker.core.common

import android.content.Context
import android.util.DisplayMetrics
import android.view.View
import androidx.recyclerview.widget.LinearSmoothScroller
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.abs

/**
* A custom LinearSmoothScroller that increases the scrolling speed quadratically
* based on the distance already scrolled.
*
* @param context The context used to access resources.
*/
class Scroller(context: Context) : LinearSmoothScroller(context) {
private var distanceScrolled = 0

/**
* Calculates the speed per pixel based on the display metrics and the distance
* already scrolled. The speed increases quadratically over time.
*
* @param displayMetrics The display metrics used to calculate the speed.
* @return The speed per pixel.
*/
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float {
return (10f / displayMetrics.densityDpi) / (1 + 0.001f * distanceScrolled * distanceScrolled)
}

/**
* Called when the target view is found. Resets the distance scrolled.
*
* @param targetView The target view.
* @param state The current state of RecyclerView.
* @param action The action to be performed.
*/
override fun onTargetFound(targetView: View, state: RecyclerView.State, action: Action) {
super.onTargetFound(targetView, state, action)
distanceScrolled = 0
}

/**
* Called when seeking the target step. Accumulates the distance scrolled.
*
* @param dx The amount of horizontal scroll.
* @param dy The amount of vertical scroll.
* @param state The current state of RecyclerView.
* @param action The action to be performed.
*/
override fun onSeekTargetStep(dx: Int, dy: Int, state: RecyclerView.State, action: Action) {
super.onSeekTargetStep(dx, dy, state, action)
distanceScrolled += abs(dy)
}
}

0 comments on commit 0df58af

Please sign in to comment.