Open RohitVerma882 opened 9 months ago
What exactly do you mean by "over scroll animation"?
https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior Are you talking about this?
I am not able to play this video.
Plays well on Google Chrome and Firefox Focus.
How to implements overscroll stretch animation for custom view on android 12 or later, https://developer.android.com/develop/ui/views/touch-and-input/gestures/scroll#kotlin
InteractiveChart sample https://android.googlesource.com/platform/development/+/master/samples/training/InteractiveChart/src/com/example/android/interactivechart/InteractiveLineGraphView.java
How to implements overscroll stretch animation for custom view on android 12 or later, https://developer.android.com/develop/ui/views/touch-and-input/gestures/scroll#kotlin
I don't know how to implement this on terminal-emulator
I don't know how to implement this on terminal-emulator
@RohitVerma882 please refer to the InteractiveChart sample
@RohitVerma882 My App implments example code snippet
// ... imports
open class OverScrollView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr),
GestureDetector.OnGestureListener {
private val scroller: OverScroller
private val gestureDetector: GestureDetector
// Edge effect / overscroll tracking objects.
private val edgeEffectTop: EdgeEffect
private val edgeEffectBottom: EdgeEffect
private val edgeEffectLeft: EdgeEffect
private val edgeEffectRight: EdgeEffect
private var edgeEffectTopActive = false
private var edgeEffectBottomActive = false
private var edgeEffectLeftActive = false
private var edgeEffectRightActive = false
// for example the max scrollX and scrollY
// screen width / 2
private val maxScrollX: Int
get() = context.resources.displayMetrics.widthPixels / 2
// screen height / 2
private val maxScrollY: Int
get() = context.resources.displayMetrics.heightPixels / 2
init {
scroller = OverScroller(context)
gestureDetector = GestureDetector(context, this)
// Sets up edge effects
edgeEffectTop = EdgeEffect(context)
edgeEffectBottom = EdgeEffect(context)
edgeEffectLeft = EdgeEffect(context)
edgeEffectRight = EdgeEffect(context)
}
override fun computeScroll() {
if (scroller.computeScrollOffset()) {
// horizontal absorb
if (
scroller.currX < 0 &&
edgeEffectLeft.isFinished() &&
!edgeEffectLeftActive
) {
edgeEffectLeft.onAbsorb(scroller.currVelocity.toInt())
edgeEffectLeftActive = true
} else if (
scroller.currX > maxScrollX &&
edgeEffectRight.isFinished() &&
!edgeEffectRightActive
) {
edgeEffectRight.onAbsorb(scroller.currVelocity.toInt())
edgeEffectRightActive = true
}
// vertical absorb
if (
scroller.currY < 0 &&
edgeEffectTop.isFinished() &&
!edgeEffectTopActive
) {
edgeEffectTop.onAbsorb(scroller.currVelocity.toInt())
edgeEffectTopActive = true
} else if (
scroller.currY > maxScrollY &&
edgeEffectBottom.isFinished() &&
!edgeEffectBottomActive
) {
edgeEffectBottom.onAbsorb(scroller.currVelocity.toInt())
edgeEffectBottomActive = true
}
scrollTo(
Math.min(Math.max(scroller.currX, 0), maxScrollX),
Math.min(Math.max(scroller.currY, 0), maxScrollY)
)
postInvalidateOnAnimation()
}
}
/**
* Draws the overscroll "glow" at the four edges of the chart region, if necessary. The edges
* of the chart region are stored in {@link #mContentRect}.
*
* @see EdgeEffect
*/
private fun drawEdgeEffect(canvas: Canvas) {
// The methods below rotate and translate the canvas as needed before drawing the glow,
// since the EdgeEffect always draws a top-glow at 0,0.
var needsInvalidate = false
if (!edgeEffectTop.isFinished()) {
val restoreCount = canvas.save()
canvas.translate(0f, 0f)
edgeEffectTop.setSize(getWidth(), getHeight())
if (edgeEffectTop.draw(canvas)) {
needsInvalidate = true
}
canvas.restoreToCount(restoreCount)
}
if (!edgeEffectBottom.isFinished()) {
val restoreCount = canvas.save()
canvas.translate(-getWidth().toFloat(), getHeight().toFloat())
edgeEffectBottom.setSize(getWidth(), getHeight())
canvas.rotate(180f, getWidth().toFloat(), 0f)
if (edgeEffectBottom.draw(canvas)) {
needsInvalidate = true
}
canvas.restoreToCount(restoreCount)
}
if (!edgeEffectLeft.isFinished()) {
val restoreCount = canvas.save()
canvas.translate(0f, getHeight().toFloat())
canvas.rotate(-90f, 0f, 0f);
edgeEffectLeft.setSize(getHeight(), getWidth())
if (edgeEffectLeft.draw(canvas)) {
needsInvalidate = true
}
canvas.restoreToCount(restoreCount)
}
if (!edgeEffectRight.isFinished()) {
val restoreCount = canvas.save()
canvas.translate(getWidth().toFloat(), 0f)
canvas.rotate(90f, 0f, 0f)
edgeEffectRight.setSize(getHeight(), getWidth())
if (edgeEffectRight.draw(canvas)) {
needsInvalidate = true
}
canvas.restoreToCount(restoreCount)
}
if (needsInvalidate) {
postInvalidateOnAnimation()
}
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// draw the edge effect
drawEdgeEffect(canvas)
}
private fun releaseEdgeEffects() {
edgeEffectTop.onRelease()
edgeEffectBottom.onRelease()
edgeEffectLeft.onRelease()
edgeEffectRight.onRelease()
}
private fun passtiveEdgeEffects() {
edgeEffectTopActive = false
edgeEffectBottomActive = false
edgeEffectLeftActive = false
edgeEffectRightActive = false
}
override fun onTouchEvent(e: MotionEvent): Boolean {
when (e.action) {
MotionEvent.ACTION_DOWN -> {
scroller.abortAnimation()
}
MotionEvent.ACTION_MOVE -> {
// do something
}
MotionEvent.ACTION_UP -> {
// callback the onUp
onUp(e)
}
}
gestureDetector.onTouchEvent(e)
return true
}
override fun onDown(e: MotionEvent): Boolean {
// when the user touches the screen
// change the edge effect states
passtiveEdgeEffects()
return true
}
override fun onScroll(e1: MotionEvent?, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
scroller.startScroll(
scroller.currX,
scroller.currY,
if(Math.abs(distanceX) > Math.abs(distanceY)) distanceX.toInt() else 0,
if(Math.abs(distanceY) > Math.abs(distanceX)) distanceY.toInt() else 0,
0
)
// vertical stretch overscroll effect
if (scroller.currY + distanceY < 0f) {
edgeEffectTop.onPullDistance(-distanceY / getHeight(), 1 - e2.getX() / getWidth())
edgeEffectTopActive = true
} else if (scroller.currY + distanceY > maxScrollY.toFloat()) {
edgeEffectBottom.onPullDistance(distanceY / getHeight(), e2.getX() / getWidth())
edgeEffectBottomActive = true
}
// horizontal stretch overscroll effect
if (scroller.currX + distanceX < 0f) {
edgeEffectLeft.onPullDistance(-distanceX / getWidth(), e2.getY() / getHeight())
edgeEffectLeftActive = true
} else if (scroller.currX + distanceX > maxScrollX.toFloat()) {
edgeEffectRight.onPullDistance(distanceX / getWidth(), e2.getY() / getHeight())
edgeEffectRightActive = true
}
return true
}
override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
// Before flinging, stops the current animation.
scroller.forceFinished(true)
scroller.fling(
// Current scroll position
scrollX,
scrollY,
if(Math.abs(velocityX) > Math.abs(velocityY)) -velocityX.toInt() else 0,
if(Math.abs(velocityY) > Math.abs(velocityX)) -velocityY.toInt() else 0,
/*
* Minimum and maximum scroll positions. The minimum scroll
* position is generally 0 and the maximum scroll position
* is generally the content size less the screen size. So if the
* content width is 2000 pixels and the screen width is 1200
* pixels, the maximum scroll offset is 800 pixels.
*/
0, maxScrollX,
0, maxScrollY,
// The edges of the content. This comes into play when using
// the EdgeEffect class to draw "glow" overlays.
getWidth() / 10,
getHeight() / 10
)
postInvalidateOnAnimation()
return true
}
private fun onUp(e: MotionEvent) {
// when the user lifts their finger off the screen
// release the edge effects
releaseEdgeEffects()
}
}
hi
Feature description
Add over scroll animation feature in termux terminal for Android 12+ devices
Additional information
In
mt manager
have this feature