Unverified Commit aa1acd8e authored by xubaolin's avatar xubaolin Committed by GitHub

Ignore unmounted parent when _debugVerifyGlobalKeyReservation for GlobalKey check (#62323)

* Ignore unmounted parent when _debugVerifyGlobalKeyReservation (#62055)

* Ignore unmounted parent when _debugVerifyGlobalKeyReservation (#62055)

* Ignore unmounted parent when _debugVerifyGlobalKeyReservation (#62055)

* Ignore unmounted parent when _debugVerifyGlobalKeyReservation (#62055)

* Ignore unmounted parent when _debugVerifyGlobalKeyReservation (#62055)

* Ignore unmounted parent when _debugVerifyGlobalKeyReservation (#62055)
parent b880dad4
......@@ -194,8 +194,8 @@ abstract class GlobalKey<T extends State<StatefulWidget>> extends Key {
assert(() {
final Map<GlobalKey, Element> keyToParent = <GlobalKey, Element>{};
_debugReservations.forEach((Element parent, Map<Element, GlobalKey> childToKey) {
// We ignore parent that are detached.
if (parent.renderObject?.attached == false)
// We ignore parent that are unmounted or detached.
if (parent._debugLifecycleState == _ElementLifecycle.defunct || parent.renderObject?.attached == false)
return;
childToKey.forEach((Element child, GlobalKey key) {
// If parent = null, the node is deactivated by its parent and is
......
......@@ -4,6 +4,7 @@
// @dart = 2.8
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
......@@ -1061,6 +1062,52 @@ void main() {
element.createChild(0, after: null);
});
testWidgets('GlobalKey - re-attach child to new parents, and the old parent is deactivated(unmounted)', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/62055
const Key key1 = GlobalObjectKey('key1');
const Key key2 = GlobalObjectKey('key2');
StateSetter setState;
int tabBarViewCnt = 2;
TabController tabController = TabController(length: tabBarViewCnt, vsync: const TestVSync(),);
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setter) {
setState = setter;
return TabBarView(
controller: tabController,
children: <Widget>[
if (tabBarViewCnt > 0) const Text('key1', key: key1,),
if (tabBarViewCnt > 1) const Text('key2', key: key2,),
],
);
},
),
));
expect(tabController.index, 0);
// switch tabs 0 -> 1
setState((){
tabController.index = 1;
});
await tester.pump(const Duration(seconds: 1)); // finish the animation
expect(tabController.index, 1);
// rebuild TabBarView that only have the 1st page with GlobalKey 'key1'
setState((){
tabBarViewCnt = 1;
tabController = TabController(length: tabBarViewCnt, vsync: const TestVSync(),);
});
await tester.pump(const Duration(seconds: 1)); // finish the animation
expect(tabController.index, 0);
});
testWidgets('Defunct setState throws exception', (WidgetTester tester) async {
StateSetter setState;
......
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