Commit dff356fc authored by Adam Barth's avatar Adam Barth

Merge pull request #2872 from abarth/fix_inherited

Inherited widgets should work across reactivations
parents 8678edfa e361c0b0
......@@ -911,10 +911,9 @@ abstract class Element implements BuildContext {
void activate(Element parent, dynamic newSlot) {
assert(_debugLifecycleState == _ElementLifecycle.inactive);
_reactivate();
_parent = parent;
_reactivate();
_updateDepth();
_updateInheritance();
attachRenderObject(newSlot);
assert(_debugLifecycleState == _ElementLifecycle.active);
}
......@@ -925,6 +924,7 @@ abstract class Element implements BuildContext {
assert(depth != null);
assert(!_active);
_active = true;
_updateInheritance();
assert(() { _debugLifecycleState = _ElementLifecycle.active; return true; });
visitChildren((Element child) => child._reactivate());
}
......@@ -939,6 +939,7 @@ abstract class Element implements BuildContext {
dependency._dependents.remove(this);
_dependencies.clear();
}
_inheritedWidgets = null;
_active = false;
assert(() { _debugLifecycleState = _ElementLifecycle.inactive; return true; });
}
......@@ -981,6 +982,7 @@ abstract class Element implements BuildContext {
}
void _updateInheritance() {
assert(_active);
_inheritedWidgets = _parent?._inheritedWidgets;
}
......@@ -1545,6 +1547,7 @@ class InheritedElement extends _ProxyElement {
@override
void _updateInheritance() {
assert(_active);
final Map<Type, InheritedElement> incomingWidgets = _parent?._inheritedWidgets;
if (incomingWidgets != null)
_inheritedWidgets = new Map<Type, InheritedElement>.from(incomingWidgets);
......
// 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 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:test/test.dart';
class TestInherited extends InheritedWidget {
TestInherited({ Key key, Widget child, this.shouldNotify: true })
: super(key: key, child: child);
final bool shouldNotify;
@override
bool updateShouldNotify(InheritedWidget oldWidget) {
return shouldNotify;
}
}
void main() {
test('Inherited notifies dependents', () {
testWidgets((WidgetTester tester) {
List<TestInherited> log = <TestInherited>[];
Builder builder = new Builder(
builder: (BuildContext context) {
log.add(context.inheritFromWidgetOfExactType(TestInherited));
return new Container();
}
);
TestInherited first = new TestInherited(child: builder);
tester.pumpWidget(first);
expect(log, equals([first]));
TestInherited second = new TestInherited(child: builder, shouldNotify: false);
tester.pumpWidget(second);
expect(log, equals([first]));
TestInherited third = new TestInherited(child: builder, shouldNotify: true);
tester.pumpWidget(third);
expect(log, equals([first, third]));
});
});
test('Update inherited when reparenting state', () {
testWidgets((WidgetTester tester) {
GlobalKey globalKey = new GlobalKey();
List<TestInherited> log = <TestInherited>[];
TestInherited build() {
return new TestInherited(
key: new UniqueKey(),
child: new Container(
key: globalKey,
child: new Builder(
builder: (BuildContext context) {
log.add(context.inheritFromWidgetOfExactType(TestInherited));
return new Container();
}
)
)
);
}
TestInherited first = build();
tester.pumpWidget(first);
expect(log, equals([first]));
TestInherited second = build();
tester.pumpWidget(second);
expect(log, equals([first, second]));
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment