Avoid rebuilding entire app when an overlay needs updating
This commit is contained in:
parent
1ab83e668f
commit
76319df5df
@ -22,31 +22,42 @@ class OverlayEntry {
|
|||||||
bool get opaque => _opaque;
|
bool get opaque => _opaque;
|
||||||
bool _opaque;
|
bool _opaque;
|
||||||
void set opaque (bool value) {
|
void set opaque (bool value) {
|
||||||
|
assert(_overlay != null);
|
||||||
if (_opaque == value)
|
if (_opaque == value)
|
||||||
return;
|
return;
|
||||||
|
_overlay.setState(() {
|
||||||
_opaque = value;
|
_opaque = value;
|
||||||
markNeedsBuild();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayState _state;
|
OverlayState _overlay;
|
||||||
|
final GlobalKey _key = new GlobalKey();
|
||||||
|
|
||||||
/// Remove this entry from the overlay.
|
/// Remove this entry from the overlay.
|
||||||
void remove() {
|
void remove() {
|
||||||
_state?._remove(this);
|
_overlay?._remove(this);
|
||||||
_state = null;
|
_overlay = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cause this entry to rebuild during the next pipeline flush.
|
/// Cause this entry to rebuild during the next pipeline flush.
|
||||||
///
|
///
|
||||||
/// You need to call this function if the output of [builder] has changed.
|
/// You need to call this function if the output of [builder] has changed.
|
||||||
void markNeedsBuild() {
|
void markNeedsBuild() {
|
||||||
// TODO(ianh): find a way to make this not rebuild the entire overlay
|
_key.currentState?.setState(() { /* the state that changed is in the builder */ });
|
||||||
_state?.setState(() {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String toString() => '$runtimeType@$hashCode(opaque: $opaque)';
|
String toString() => '$runtimeType@$hashCode(opaque: $opaque)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _OverlayEntry extends StatefulComponent {
|
||||||
|
_OverlayEntry(OverlayEntry entry) : entry = entry, super(key: entry._key);
|
||||||
|
final OverlayEntry entry;
|
||||||
|
_OverlayEntryState createState() => new _OverlayEntryState();
|
||||||
|
}
|
||||||
|
class _OverlayEntryState extends State<_OverlayEntry> {
|
||||||
|
Widget build(BuildContext context) => config.entry.builder(context);
|
||||||
|
}
|
||||||
|
|
||||||
/// A [Stack] of entries that can be managed independently.
|
/// A [Stack] of entries that can be managed independently.
|
||||||
class Overlay extends StatefulComponent {
|
class Overlay extends StatefulComponent {
|
||||||
Overlay({
|
Overlay({
|
||||||
@ -77,9 +88,9 @@ class OverlayState extends State<Overlay> {
|
|||||||
/// If [above] is non-null, the entry is inserted just above [above].
|
/// If [above] is non-null, the entry is inserted just above [above].
|
||||||
/// Otherwise, the entry is inserted on top.
|
/// Otherwise, the entry is inserted on top.
|
||||||
void insert(OverlayEntry entry, { OverlayEntry above }) {
|
void insert(OverlayEntry entry, { OverlayEntry above }) {
|
||||||
assert(entry._state == null);
|
assert(entry._overlay == null);
|
||||||
assert(above == null || (above._state == this && _entries.contains(above)));
|
assert(above == null || (above._overlay == this && _entries.contains(above)));
|
||||||
entry._state = this;
|
entry._overlay = this;
|
||||||
setState(() {
|
setState(() {
|
||||||
int index = above == null ? _entries.length : _entries.indexOf(above) + 1;
|
int index = above == null ? _entries.length : _entries.indexOf(above) + 1;
|
||||||
_entries.insert(index, entry);
|
_entries.insert(index, entry);
|
||||||
@ -91,10 +102,10 @@ class OverlayState extends State<Overlay> {
|
|||||||
/// If [above] is non-null, the entries are inserted just above [above].
|
/// If [above] is non-null, the entries are inserted just above [above].
|
||||||
/// Otherwise, the entries are inserted on top.
|
/// Otherwise, the entries are inserted on top.
|
||||||
void insertAll(Iterable<OverlayEntry> entries, { OverlayEntry above }) {
|
void insertAll(Iterable<OverlayEntry> entries, { OverlayEntry above }) {
|
||||||
assert(above == null || (above._state == this && _entries.contains(above)));
|
assert(above == null || (above._overlay == this && _entries.contains(above)));
|
||||||
for (OverlayEntry entry in entries) {
|
for (OverlayEntry entry in entries) {
|
||||||
assert(entry._state == null);
|
assert(entry._overlay == null);
|
||||||
entry._state = this;
|
entry._overlay = this;
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
int index = above == null ? _entries.length : _entries.indexOf(above) + 1;
|
int index = above == null ? _entries.length : _entries.indexOf(above) + 1;
|
||||||
@ -136,10 +147,7 @@ class OverlayState extends State<Overlay> {
|
|||||||
|
|
||||||
for (int i = _entries.length - 1; i >= 0; --i) {
|
for (int i = _entries.length - 1; i >= 0; --i) {
|
||||||
OverlayEntry entry = _entries[i];
|
OverlayEntry entry = _entries[i];
|
||||||
backwardsChildren.add(new KeyedSubtree(
|
backwardsChildren.add(new _OverlayEntry(entry));
|
||||||
key: new ObjectKey(entry),
|
|
||||||
child: entry.builder(context)
|
|
||||||
));
|
|
||||||
if (entry.opaque)
|
if (entry.opaque)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user