Previously OverflowBox was only useful to set a tight constraint on the
child. Now it can be used to set any constraint, it just overrides any
constraint from the parent that is not set to null on the
RenderOverflowBox object when giving the constraints to the child.
Initial snap offset support for ScrollableWidgetList (and ScrollableList<T>) and ScrollableMixedWidgetList. If a ```toSnapOffset(scrollOffset)``` function is provided, fling Scrolls will coast to the returned value. If ```alignmentOffset``` is specified then fling scrolls conclude when toSnapOffset's value lines up with the Scrollable widget's origin + alignmentOffset. For example if the Scrollable widget's height was 200.0, and alignmentOffset:100.0 was specified, then fling scrolls would end with the value returned by toSnapOffset() lined up with the center of the Scrollable.
This approach to Scrollable snapping assumes that the layout of whatever the Scrollable contains is known at the outset. This is often true however a ScrollableMixedWidgetList may not know its items' sizes until they've been reached by scrolling.
This is a first cut at snapping support. Among the things that remain to be done:
- Scrolling limits trump snapping. Snapping should probably trump scrolling limits.
- Drag scrolls aren't snapped. This may be desirable so perhaps the feature should be controlled with a flag.
- Specifying alignmentOffset as a percentage would probably be more convenient.
- It would be nice if one could wrap items in a SnapOffset value like: ```new SnapOffset(0.5, child: myItem)``` to snap to the center of the item.
Updated the CardCollection example: snapping and fixed size items can be turned on/off with Drawer checkboxes.
EditableText is now rendered using a custom RenderObject
(RenderEditableParagraph). RenderEditableParagraph draws the cursor,
handles scroll offsets, and provides feedback about the size of the text for
use by the scroll behavior.
Having UniqueComponent automatically generate its own key is a trap. If
anyone ever creates a UniqueComponent in a build function (rather than
ahead of time) and forgets to pass a key, then that entire subtree is
going to be rebuilt, including layout, every time it's updated. Since
there's basically no way for us to catch this, we should at least force
the author to see the explicit "new GlobalKey()" call in their code.
Tapping on the menu item didn't animate the checkbox because the menu
takes 300ms to animate entirely away while the checkbox takes 200ms to
animate checked, and since the item with the checkbox was at the bottom,
we were only seeing about 60ms of the entire checkbox animation, which
isn't enough to notice it. So I moved it to the top of the menu.
Tapping on the checkbox didn't animate because nothing caused the menu
to rebuild when the callback was invoked. To trigger a rebuild, I now
call navigator.setState() explicitly, after changing out local state.
To make tapping the checkbox remove the menu, I also explicitly call
navigator.pop() in the code that handles the check. (I still explicitly
change the checkbox to show that that's possible. In principle one could
just treat the checkbox as an inert widget that happens to trigger pop,
and do all the checking/unchecking in the switch statement.)
I also made some minor style tweaks to files I was looking at while
dealing with this issue.
This changes how SnackBar works so you can use it anywhere, not just on
the bottom edge of the screen (it used to rely on overflowing its bounds
and having negative offsets... I'm not really sure how hit testing
worked on it before!).
To do this I introduced a new RenderBox, RenderOverflowBox, that lets
you set your child's size independent of your own. I needed this so that
the snack bar could use a SquashTransition to change its size, while not
affecting the layout of its child. This is exposed as OverflowBox in
fn3. I'm not sure if it's the best API. It doesn't let you position the
child (which is an issue if the size you give is smaller), it doesn't
let you give a loose constraint (which maybe you might want?). But it
handles this use case, so for now it's probably ok.
Making the FAB get repositioned out of the way of the Snack Bar is now
done in the Scaffold, which is in charge of positioning both of those
and is the place that knows that both exist.
This patch makes a number of changes:
1) buildDirtyComponents now prevents all calls to setState, not just those
higher in the tree. This change is necessary for consistency with
MixedViewport and HomogeneousViewport because those widgets already build
subwidgets with that restriction. If the "normal" build didn't enforce that
rule, then some widgets would break when put inside a mixed or homogeneous
viewport.
2) We now notify global key listeners in a microtask after beginFrame. That
means setState is legal in these callbacks and that we'll produce another
frame if someone calls setState in such a callback.
Also:
- Make Dismissable report when it starts squashing, since otherwise we
don't invalidate the list early enough and it gets mad that it wasn't
told one of its children had changed size.
- Have Dismissable check that it gets removed after it's dismissed, to
avoid having lots of redundant widgets around.
- Start tracking the height of each child of a MixedViewport, so that we
don't accumulate floating point errors when a child jiggles up and down.
- Have _childOffsets reuse its storage space rather than newing up a new
copy each time we reset the cache.
- Avoid double-updating child sizes when handling mixed viewport invalidations.