You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Added
smoothScrollToPosition(int), on all three views, animates the cell holding
the position to parchment_snapPosition the way a fling gets there, where setSelection jumps. It runs at RecyclerView's programmatic speed, 25 ms
per inch, four times a snap's: a cell already laid out is landed on with one
decelerating scroll of exactly its snap distance; a cell that is not is
sought at a constant speed by the distance extrapolated from the edge cell's
size plus a viewport of runway, handed to the landing in the frame it is
laid out, and sought again from wherever it is whenever less than a viewport
of runway is left, so the motion stays even when the cells between were
larger than the estimate assumed. The landing is not capped at half a
second, so a long scroll decelerates from the seek's speed rather than
snapping the rest of the way. It obeys every bound a fling obeys: android:padding*, parchment_scrollWithinContent, under which a cell the
bound holds short of its snap point decelerates onto the bound and rests
there, and parchment_isCircularScroll, under which it takes the shorter
way round. A parchment_isViewPager view is crossed page by page rather
than held to one, which needed the page clamp to learn that an animation is
not a gesture. It reports settling then idle to the scroll listener, and
under parchment_selectOnSnap selects the cell at the snap position when it
comes to rest, once. The position is clamped to the adapter; before the first
layout, on an empty adapter, or when the cell is already at its snap point
nothing happens; it is ignored while a finger is down, and a touch cancels it
like a fling. Under onScreen it scrolls the minimum that shows the cell
whole. A position asked for before the first layout is not remembered; a
pending target is a follow-up (#54, asked for in #19).
Changed
A jump ends a running animation. setSelection and a data set change now
stop whatever was moving the content, a fling included, in the layout pass
the jump asks for, snapping whatever residual the jump left, so the view
rests with the incoming cell at its snap point and reports one idle; the
fling used to carry on from the jumped offset. At rest nothing changes: no
frame runs and nothing is reported.
Breaking:LayoutManager gains an abstract getCellBreadth, a cell's
extent across the scroll axis, and measureBreadth, which AbstractAdapterView.onMeasure asks for the view's size across it; ScrollDirectionManager gains the cross-axis spec, padding and width/height
mappings that serve them. All are implementation details the views build and
call for themselves, so nothing outside the library should be subclassing or
calling them.
Fixed
parchment_selectOnSnap reported the selection a stop made only on the next
layout pass, so a fling that ended exactly on a snap point, with no residual
snap to run a further frame, selected the cell but did not tell the OnItemSelectedListener until something else laid the view out. A frame
that ends at rest now reports the selection its stop made, which is what
every smoothScrollToPosition landing needs
(aFlingThatEndsOnASnapPoint_withSelectOnSnap_reportsTheSelectionWithoutALayoutPass).
Two consequences to know about: under parchment_selectOnSnap a data set
change at rest that keeps or grows the count now reports its unchanged
selection one layout pass earlier, the same cell in the same place, once;
and a jump that lands mid-animation reports its selection where the cell is
at the jump, after which the residual snap moves it the few pixels to its
snap point, as it already did on main with the fling still running. Under parchment_isCircularScroll with parchment_selectOnSnap, a tap on a cell
reports that cell and then the cell nearest the start edge, because the
stop's snap selects the nearest cell to the onScreen position circular
scrolling forces; main did the same silently, and this is now reported
rather than fixed.
A fling, snap or smooth scroll that ran to rest within its first frame, as a
short snap does and as any animation does when the main thread stalls for a
frame, reported its displacement but no scroll state: the dispatcher reports
a change at the end of a frame and the frame ended where it began, at idle. It now reports the state the frame ran in before the state it ended
in, when the frame moved the content, so such a frame reports settling
then idle after its onScrolled and a frame that moved nothing still
reports nothing
(aSmoothScrollThatEndsInItsFirstFrame_stillReportsSettlingThenIdle, aFlingThatEndsInItsFirstFrame_stillReportsSettlingThenIdle).
android:layout_height="wrap_content" on a horizontal view and android:layout_width="wrap_content" on a vertical one used to take every
pixel the parent had left, pushing the next sibling of a LinearLayout off
the screen: onMeasure set the measured size to the spec size whatever the
spec's mode, so AT_MOST was treated as EXACTLY. Across the scroll axis a ListView now measures to its largest cell and a GridView to its largest
row or column, the spacing between the views of the group included, plus android:padding*, capped at the size offered under AT_MOST and uncapped
under UNSPECIFIED. EXACTLY is untouched, so match_parent and a fixed
size lay out exactly as before. Along the scroll axis wrap_content still
fills the parent, since wrapping there would mean measuring every item in the
adapter, and GridPatternView, whose cells are sized from the view, still
fills it on both axes. The size comes from the cells present at measure time:
the cells laid out, or before the first layout the cells that fill the
viewport from the start position, obtained through the recycler and handed
back to it the way the platform ListView measures under AT_MOST. That
first estimate cannot see a cell the layout back-fills before the start
position, one the over-scroll correction pulls in, or one a scroll reveals
later, so a layout that draws a cell larger than the size it was measured to
asks the view for one more layout, and the next measure, which reads the
drawn cells, grows the view to it. Cells of varying size across the scroll
axis are therefore better served by a fixed size, because the view resizes
as they come into view (#59, the remaining half of #10).
A horizontal ListView gave its children the mode of its own width spec as
their height mode, and a GridView did the same for the views it obtains for
a jump. They now take the mode of the height spec. Under wrap_content that
is what lets a match_parent child measure to its content rather than to
the whole height the parent offered; under a bounded width and an exact
height, a horizontal list inside a HorizontalScrollView or a wrap_content-wide parent, a match_parent child is now given the exact
height instead of a bound it measured itself to zero against. Under EXACTLY
on both axes nothing changes.