drag the list past either end: the content compresses towards the edge rather than sliding off it
mounted as overscroll
why it looks like this
The end of a list, the way Windows Phone ended one: the content follows the finger past the boundary, showing the page behind it, and rubber-bands back when it lets go.
This was a scale until it was read properly, and the correction is the most useful thing in this file. The visual states Microsoft added to ScrollViewer in Windows Phone 7.1 are named HorizontalCompression and VerticalCompression, and the whole of the first implementation was built on that word: the content was squeezed towards the edge being pushed, the boundary held still, and nothing empty ever appeared. The design guidelines say the opposite, in a sentence nobody had gone looking for:
`` When the end of the list is reached, it will then scroll up to display the empty section and "rubber band" back to rest in place. Flicking at the end of the list causes it to rubber band back; the list won't wrap to the beginning. — LongListSelector design guidelines, jj735577 ``
"Display the empty section" settles it: a squeeze cannot produce one, because a squeeze is defined by the boundary not moving. The word "compression" describes the manipulation — the scroll being damped past its end — and not the pixels, which is also why those visual states carry no storyboard: they are there so an application can notice the damping, not so it can draw it.
A name is not a description, and this cost three rounds of tuning something that was the wrong effect. The class keeps its name because research, B-38 and B-45 all cite it; the parameters do not, because a parameter called maxCompression that sets a translation distance is a claim in a signature.
This is the same argument as the tilt, one line further down KvadrantTheme. That theme replaces LocalIndication because a Metro surface that ripples is not a Metro surface; it had until B-38 left LocalOverscrollFactory alone, so on Android a Metro list ended with Android's stretch. A finger meets this every time a list runs out, which makes it about as frequent as a press and about as recognisable.
What Microsoft published is that it happens, not how far or how fast. The states are documented and none of their numbers are, so how far the content travels, how the resistance builds and how it returns are this project's own: parameters rather than constants, named as ours here, the same rule research §1.10 applies to the panorama's peek.
maxOffset | how far the content travels past the boundary at the limit, as a fraction of the viewport. Ours. |
resistance | how much finger travel it takes to reach that limit, as a multiple of the viewport. Ours, and the strongest lever on how the effect feels — see KvadrantOverscroll.DEFAULT_RESISTANCE, which was raised fourfold once a diagram showed a flick spending the whole of it in two frames. |
flingReference | the speed, in viewports per second, at which a fling arriving at the end spends about two thirds of what is available. Ours; see DEFAULT_FLING_REFERENCE. |
Read it: kvadrant-core/src/commonMain/kotlin/io/github/youndie/kvadrant/indication/KvadrantOverscroll.kt · the full signature and every parameter