mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add PageStorage support to Navigator2
This commit is contained in:
parent
e904ab5773
commit
4877c06149
@ -8,6 +8,7 @@ import 'basic.dart';
|
||||
import 'framework.dart';
|
||||
import 'navigator2.dart';
|
||||
import 'overlay.dart';
|
||||
import 'page_storage.dart';
|
||||
import 'transitions.dart';
|
||||
|
||||
// TODO(abarth): Should we add a type for the result?
|
||||
@ -81,8 +82,9 @@ class _PageState extends State<_Page> {
|
||||
Widget build(BuildContext context) {
|
||||
if (config.route._offstage) {
|
||||
return new OffStage(
|
||||
child: new KeyedSubtree(
|
||||
child: new PageStorage(
|
||||
key: _subtreeKey,
|
||||
bucket: config.route._storageBucket,
|
||||
child: _invokeBuilder()
|
||||
)
|
||||
);
|
||||
@ -93,8 +95,9 @@ class _PageState extends State<_Page> {
|
||||
child: new FadeTransition(
|
||||
performance: config.route.performance,
|
||||
opacity: _opacity,
|
||||
child: new KeyedSubtree(
|
||||
child: new PageStorage(
|
||||
key: _subtreeKey,
|
||||
bucket: config.route._storageBucket,
|
||||
child: _invokeBuilder()
|
||||
)
|
||||
)
|
||||
@ -132,6 +135,8 @@ class PageRoute extends TransitionRoute {
|
||||
Duration get transitionDuration => const Duration(milliseconds: 150);
|
||||
List<Widget> createWidgets() => [ new _Page(key: pageKey, route: this) ];
|
||||
|
||||
final PageStorageBucket _storageBucket = new PageStorageBucket();
|
||||
|
||||
bool get offstage => _offstage;
|
||||
bool _offstage = false;
|
||||
void set offstage (bool value) {
|
||||
|
||||
102
packages/flutter/lib/src/widgets/page_storage.dart
Normal file
102
packages/flutter/lib/src/widgets/page_storage.dart
Normal file
@ -0,0 +1,102 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'framework.dart';
|
||||
|
||||
class _StorageEntryIdentifier {
|
||||
Type clientType;
|
||||
List<Key> keys;
|
||||
void addKey(Key key) {
|
||||
assert(key != null);
|
||||
assert(key is! GlobalKey);
|
||||
keys ??= <Key>[];
|
||||
keys.add(key);
|
||||
}
|
||||
GlobalKey scopeKey;
|
||||
bool operator ==(dynamic other) {
|
||||
if (other is! _StorageEntryIdentifier)
|
||||
return false;
|
||||
final _StorageEntryIdentifier typedOther = other;
|
||||
if (clientType != typedOther.clientType ||
|
||||
scopeKey != typedOther.scopeKey ||
|
||||
keys?.length != typedOther.keys?.length)
|
||||
return false;
|
||||
if (keys != null) {
|
||||
for (int index = 0; index < keys.length; index += 1) {
|
||||
if (keys[index] != typedOther.keys[index])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
int get hashCode {
|
||||
int value = 373;
|
||||
value = 37 * value + clientType.hashCode;
|
||||
value = 37 * value + scopeKey.hashCode;
|
||||
if (keys != null) {
|
||||
for (Key key in keys)
|
||||
value = 37 * value + key.hashCode;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
class PageStorageBucket {
|
||||
_StorageEntryIdentifier _computeStorageIdentifier(BuildContext context) {
|
||||
_StorageEntryIdentifier result = new _StorageEntryIdentifier();
|
||||
result.clientType = context.widget.runtimeType;
|
||||
Key lastKey = context.widget.key;
|
||||
if (lastKey is! GlobalKey) {
|
||||
context.visitAncestorElements((Element element) {
|
||||
if (element.widget.key is GlobalKey) {
|
||||
lastKey = element.widget.key;
|
||||
return false;
|
||||
} else if (element.widget.key != null) {
|
||||
result.addKey(element.widget.key);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
assert(lastKey is GlobalKey);
|
||||
result.scopeKey = lastKey;
|
||||
return result;
|
||||
}
|
||||
|
||||
Map<_StorageEntryIdentifier, dynamic> _storage;
|
||||
void writeState(BuildContext context, dynamic data) {
|
||||
_storage ??= <_StorageEntryIdentifier, dynamic>{};
|
||||
_storage[_computeStorageIdentifier(context)] = data;
|
||||
}
|
||||
dynamic readState(BuildContext context) {
|
||||
return _storage != null ? _storage[_computeStorageIdentifier(context)] : null;
|
||||
}
|
||||
}
|
||||
|
||||
class PageStorage extends StatelessComponent {
|
||||
PageStorage({
|
||||
Key key,
|
||||
this.child,
|
||||
this.bucket
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget child;
|
||||
final PageStorageBucket bucket;
|
||||
|
||||
/// Might return null if there is no PageStorage in this context.
|
||||
static PageStorageBucket of(BuildContext context) {
|
||||
PageStorageBucket result;
|
||||
context.visitAncestorElements((Element element) {
|
||||
Widget widget = element.widget;
|
||||
if (widget is PageStorage) {
|
||||
result = widget.bucket;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
Widget build(BuildContext context) => child;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user