A whole lot of stuff
This commit is contained in:
parent
faf319322a
commit
ad850d2be6
50 changed files with 3013 additions and 213 deletions
|
|
@ -1,6 +1,41 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Waits for a route's push/pop transition, if one is still in progress, to
|
||||
/// finish. Needed before capturing a highlighted target's on-screen
|
||||
/// position via `RenderBox.localToGlobal` (see `MainShell._waitForTargets`
|
||||
/// / `_SpotlightedDataSettingsScreen`'s `_showSpotlight` in
|
||||
/// backup_reminder.dart, both of which push a [MaterialPageRoute] and then
|
||||
/// spotlight something on it): a [RenderBox] reports `hasSize` — and a
|
||||
/// real, but not yet final, global position — as soon as its first layout
|
||||
/// pass completes, which happens well before a [MaterialPageRoute]'s
|
||||
/// ~300ms slide-in transition actually settles. Capturing the position too
|
||||
/// early bakes in wherever the page was mid-slide, which is what produced
|
||||
/// a spotlight rectangle visibly shifted from its target.
|
||||
///
|
||||
/// Takes the [Animation] directly — rather than a [BuildContext] to look
|
||||
/// one up via `ModalRoute.of` — because the caller doesn't always have a
|
||||
/// [BuildContext] that's actually inside the route in question: `MainShell`
|
||||
/// pushes the route from its own (different, already-settled) route, so
|
||||
/// `ModalRoute.of(mainShellContext)` would resolve to the wrong one.
|
||||
/// Passing null (nothing to wait for) or an already-[AnimationStatus.completed]
|
||||
/// animation both resolve immediately, so it's safe to call unconditionally.
|
||||
Future<void> waitForRouteTransition(Animation<double>? animation) async {
|
||||
if (animation == null || animation.status == AnimationStatus.completed) return;
|
||||
final completer = Completer<void>();
|
||||
void listener(AnimationStatus status) {
|
||||
if (status == AnimationStatus.completed || status == AnimationStatus.dismissed) {
|
||||
completer.complete();
|
||||
}
|
||||
}
|
||||
|
||||
animation.addStatusListener(listener);
|
||||
await completer.future;
|
||||
animation.removeStatusListener(listener);
|
||||
}
|
||||
|
||||
/// The full-screen "spotlight" shown by one step of the first-launch
|
||||
/// guided tour: a dimmed barrier with a cut-out hole around each of
|
||||
/// [targetKeys]' current on-screen positions (or, for any key that isn't
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue