Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
bb4a2e8b
Commit
bb4a2e8b
authored
8 years ago
by
Ian Hickson
Committed by
GitHub
8 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement detachChild for LayoutBuilder (#5860)
Fixes
https://github.com/flutter/flutter/issues/5840
parent
cb6b4c95
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
148 additions
and
21 deletions
+148
-21
binding.dart
packages/flutter/lib/src/widgets/binding.dart
+6
-0
framework.dart
packages/flutter/lib/src/widgets/framework.dart
+37
-18
layout_builder.dart
packages/flutter/lib/src/widgets/layout_builder.dart
+6
-0
lazy_block.dart
packages/flutter/lib/src/widgets/lazy_block.dart
+13
-1
overlay.dart
packages/flutter/lib/src/widgets/overlay.dart
+2
-1
table.dart
packages/flutter/lib/src/widgets/table.dart
+0
-1
virtual_viewport.dart
packages/flutter/lib/src/widgets/virtual_viewport.dart
+12
-0
reparent_state_with_layout_builder_test.dart
.../test/widget/reparent_state_with_layout_builder_test.dart
+72
-0
No files found.
packages/flutter/lib/src/widgets/binding.dart
View file @
bb4a2e8b
...
@@ -471,6 +471,12 @@ class RenderObjectToWidgetElement<T extends RenderObject> extends RootRenderObje
...
@@ -471,6 +471,12 @@ class RenderObjectToWidgetElement<T extends RenderObject> extends RootRenderObje
visitor
(
_child
);
visitor
(
_child
);
}
}
@override
void
detachChild
(
Element
child
)
{
assert
(
child
==
_child
);
_child
=
null
;
}
@override
@override
void
mount
(
Element
parent
,
dynamic
newSlot
)
{
void
mount
(
Element
parent
,
dynamic
newSlot
)
{
assert
(
parent
==
null
);
assert
(
parent
==
null
);
...
...
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/framework.dart
View file @
bb4a2e8b
...
@@ -1143,6 +1143,13 @@ class _InactiveElements {
...
@@ -1143,6 +1143,13 @@ class _InactiveElements {
void
_unmount
(
Element
element
)
{
void
_unmount
(
Element
element
)
{
assert
(
element
.
_debugLifecycleState
==
_ElementLifecycle
.
inactive
);
assert
(
element
.
_debugLifecycleState
==
_ElementLifecycle
.
inactive
);
assert
(()
{
if
(
debugPrintGlobalKeyedWidgetLifecycle
)
{
if
(
element
.
widget
.
key
is
GlobalKey
)
debugPrint
(
'Discarding
$element
from inactive elements list.'
);
}
return
true
;
});
element
.
unmount
();
element
.
unmount
();
assert
(
element
.
_debugLifecycleState
==
_ElementLifecycle
.
defunct
);
assert
(
element
.
_debugLifecycleState
==
_ElementLifecycle
.
defunct
);
element
.
visitChildren
((
Element
child
)
{
element
.
visitChildren
((
Element
child
)
{
...
@@ -1720,7 +1727,15 @@ abstract class Element implements BuildContext {
...
@@ -1720,7 +1727,15 @@ abstract class Element implements BuildContext {
visitChildren
(
visitor
);
visitChildren
(
visitor
);
}
}
bool
detachChild
(
Element
child
)
=>
false
;
/// Remove the given child.
///
/// This updates the child model such that [visitChildren] does not walk that
/// child anymore.
///
/// The element must have already been deactivated when this is called,
/// meaning that its parent should be null.
@protected
void
detachChild
(
Element
child
);
/// This method is the core of the system.
/// This method is the core of the system.
///
///
...
@@ -1868,11 +1883,14 @@ abstract class Element implements BuildContext {
...
@@ -1868,11 +1883,14 @@ abstract class Element implements BuildContext {
return
null
;
return
null
;
assert
(()
{
assert
(()
{
if
(
debugPrintGlobalKeyedWidgetLifecycle
)
if
(
debugPrintGlobalKeyedWidgetLifecycle
)
debugPrint
(
'Attempting to take
$element
from
${element._parent ?? "inactive elements list"}
to put in
$this
'
);
debugPrint
(
'Attempting to take
$element
from
${element._parent ?? "inactive elements list"}
to put in
$this
.
'
);
return
true
;
return
true
;
});
});
if
(
element
.
_parent
!=
null
&&
!
element
.
_parent
.
detachChild
(
element
))
final
Element
parent
=
element
.
_parent
;
return
null
;
if
(
parent
!=
null
)
{
parent
.
deactivateChild
(
element
);
parent
.
detachChild
(
element
);
}
assert
(
element
.
_parent
==
null
);
assert
(
element
.
_parent
==
null
);
owner
.
_inactiveElements
.
remove
(
element
);
owner
.
_inactiveElements
.
remove
(
element
);
return
element
;
return
element
;
...
@@ -1930,6 +1948,11 @@ abstract class Element implements BuildContext {
...
@@ -1930,6 +1948,11 @@ abstract class Element implements BuildContext {
void
_activateWithParent
(
Element
parent
,
dynamic
newSlot
)
{
void
_activateWithParent
(
Element
parent
,
dynamic
newSlot
)
{
assert
(
_debugLifecycleState
==
_ElementLifecycle
.
inactive
);
assert
(
_debugLifecycleState
==
_ElementLifecycle
.
inactive
);
_parent
=
parent
;
_parent
=
parent
;
assert
(()
{
if
(
debugPrintGlobalKeyedWidgetLifecycle
)
debugPrint
(
'Reactivating
$this
(now child of
$_parent
).'
);
return
true
;
});
_updateDepth
(
_parent
.
depth
);
_updateDepth
(
_parent
.
depth
);
_activateRecursively
(
this
);
_activateRecursively
(
this
);
attachRenderObject
(
newSlot
);
attachRenderObject
(
newSlot
);
...
@@ -1947,11 +1970,6 @@ abstract class Element implements BuildContext {
...
@@ -1947,11 +1970,6 @@ abstract class Element implements BuildContext {
/// instead of being unmounted (see [unmount]).
/// instead of being unmounted (see [unmount]).
@mustCallSuper
@mustCallSuper
void
activate
()
{
void
activate
()
{
assert
(()
{
if
(
debugPrintGlobalKeyedWidgetLifecycle
)
debugPrint
(
'Reactivating
$this
(child of
$_parent
).'
);
return
true
;
});
assert
(
_debugLifecycleState
==
_ElementLifecycle
.
inactive
);
assert
(
_debugLifecycleState
==
_ElementLifecycle
.
inactive
);
assert
(
widget
!=
null
);
assert
(
widget
!=
null
);
assert
(
owner
!=
null
);
assert
(
owner
!=
null
);
...
@@ -2387,11 +2405,9 @@ abstract class ComponentElement extends BuildableElement {
...
@@ -2387,11 +2405,9 @@ abstract class ComponentElement extends BuildableElement {
}
}
@override
@override
bool
detachChild
(
Element
child
)
{
void
detachChild
(
Element
child
)
{
assert
(
child
==
_child
);
assert
(
child
==
_child
);
deactivateChild
(
_child
);
_child
=
null
;
_child
=
null
;
return
true
;
}
}
}
}
...
@@ -3026,6 +3042,11 @@ abstract class RootRenderObjectElement extends RenderObjectElement {
...
@@ -3026,6 +3042,11 @@ abstract class RootRenderObjectElement extends RenderObjectElement {
class
LeafRenderObjectElement
extends
RenderObjectElement
{
class
LeafRenderObjectElement
extends
RenderObjectElement
{
LeafRenderObjectElement
(
LeafRenderObjectWidget
widget
):
super
(
widget
);
LeafRenderObjectElement
(
LeafRenderObjectWidget
widget
):
super
(
widget
);
@override
void
detachChild
(
Element
child
)
{
assert
(
false
);
}
@override
@override
void
insertChildRenderObject
(
RenderObject
child
,
dynamic
slot
)
{
void
insertChildRenderObject
(
RenderObject
child
,
dynamic
slot
)
{
assert
(
false
);
assert
(
false
);
...
@@ -3064,11 +3085,9 @@ class SingleChildRenderObjectElement extends RenderObjectElement {
...
@@ -3064,11 +3085,9 @@ class SingleChildRenderObjectElement extends RenderObjectElement {
}
}
@override
@override
bool
detachChild
(
Element
child
)
{
void
detachChild
(
Element
child
)
{
assert
(
child
==
_child
);
assert
(
child
==
_child
);
deactivateChild
(
_child
);
_child
=
null
;
_child
=
null
;
return
true
;
}
}
@override
@override
...
@@ -3157,10 +3176,10 @@ class MultiChildRenderObjectElement extends RenderObjectElement {
...
@@ -3157,10 +3176,10 @@ class MultiChildRenderObjectElement extends RenderObjectElement {
}
}
@override
@override
bool
detachChild
(
Element
child
)
{
void
detachChild
(
Element
child
)
{
assert
(
_children
.
contains
(
child
));
assert
(!
_detachedChildren
.
contains
(
child
));
_detachedChildren
.
add
(
child
);
_detachedChildren
.
add
(
child
);
deactivateChild
(
child
);
return
true
;
}
}
@override
@override
...
...
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/layout_builder.dart
View file @
bb4a2e8b
...
@@ -69,6 +69,12 @@ class _LayoutBuilderElement extends RenderObjectElement {
...
@@ -69,6 +69,12 @@ class _LayoutBuilderElement extends RenderObjectElement {
visitor
(
_child
);
visitor
(
_child
);
}
}
@override
void
detachChild
(
Element
child
)
{
assert
(
child
==
_child
);
_child
=
null
;
}
@override
@override
void
mount
(
Element
parent
,
dynamic
newSlot
)
{
void
mount
(
Element
parent
,
dynamic
newSlot
)
{
super
.
mount
(
parent
,
newSlot
);
// Creates the renderObject.
super
.
mount
(
parent
,
newSlot
);
// Creates the renderObject.
...
...
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/lazy_block.dart
View file @
bb4a2e8b
...
@@ -510,6 +510,18 @@ class _LazyBlockElement extends RenderObjectElement {
...
@@ -510,6 +510,18 @@ class _LazyBlockElement extends RenderObjectElement {
visitor
(
child
);
visitor
(
child
);
}
}
@override
void
detachChild
(
Element
child
)
{
assert
(()
{
// TODO(ianh): implement detachChild for LazyBlock
throw
new
FlutterError
(
'LazyBlock does not yet support GlobalKey reparenting of its children.
\n
'
'As a temporary workaround, wrap the child with the GlobalKey in a '
'Container or other harmless child.'
);
});
}
@override
@override
void
mount
(
Element
parent
,
dynamic
newSlot
)
{
void
mount
(
Element
parent
,
dynamic
newSlot
)
{
super
.
mount
(
parent
,
newSlot
);
super
.
mount
(
parent
,
newSlot
);
...
@@ -585,7 +597,7 @@ class _LazyBlockElement extends RenderObjectElement {
...
@@ -585,7 +597,7 @@ class _LazyBlockElement extends RenderObjectElement {
void
performRebuild
()
{
void
performRebuild
()
{
IndexedWidgetBuilder
builder
=
widget
.
delegate
.
buildItem
;
IndexedWidgetBuilder
builder
=
widget
.
delegate
.
buildItem
;
List
<
Widget
>
widgets
=
<
Widget
>[];
List
<
Widget
>
widgets
=
<
Widget
>[];
for
(
int
i
=
0
;
i
<
_children
.
length
;
++
i
)
{
for
(
int
i
=
0
;
i
<
_children
.
length
;
i
+=
1
)
{
int
logicalIndex
=
_firstChildLogicalIndex
+
i
;
int
logicalIndex
=
_firstChildLogicalIndex
+
i
;
Widget
childWidget
=
_callBuilder
(
builder
,
logicalIndex
);
Widget
childWidget
=
_callBuilder
(
builder
,
logicalIndex
);
if
(
childWidget
==
null
)
if
(
childWidget
==
null
)
...
...
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/overlay.dart
View file @
bb4a2e8b
...
@@ -438,9 +438,10 @@ class _TheatreElement extends RenderObjectElement {
...
@@ -438,9 +438,10 @@ class _TheatreElement extends RenderObjectElement {
if
(
child
==
_onstage
)
{
if
(
child
==
_onstage
)
{
_onstage
=
null
;
_onstage
=
null
;
}
else
{
}
else
{
assert
(
_offstage
.
contains
(
child
));
assert
(!
_detachedOffstageChildren
.
contains
(
child
));
_detachedOffstageChildren
.
add
(
child
);
_detachedOffstageChildren
.
add
(
child
);
}
}
deactivateChild
(
child
);
return
true
;
return
true
;
}
}
...
...
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/table.dart
View file @
bb4a2e8b
...
@@ -279,7 +279,6 @@ class _TableElement extends RenderObjectElement {
...
@@ -279,7 +279,6 @@ class _TableElement extends RenderObjectElement {
@override
@override
bool
detachChild
(
Element
child
)
{
bool
detachChild
(
Element
child
)
{
_detachedChildren
.
add
(
child
);
_detachedChildren
.
add
(
child
);
deactivateChild
(
child
);
return
true
;
return
true
;
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/virtual_viewport.dart
View file @
bb4a2e8b
...
@@ -100,6 +100,18 @@ abstract class VirtualViewportElement extends RenderObjectElement {
...
@@ -100,6 +100,18 @@ abstract class VirtualViewportElement extends RenderObjectElement {
visitor
(
child
);
visitor
(
child
);
}
}
@override
void
detachChild
(
Element
child
)
{
assert
(()
{
// TODO(ianh): implement detachChild for VirtualViewport
throw
new
FlutterError
(
'
$runtimeType
does not yet support GlobalKey reparenting of its children.
\n
'
'As a temporary workaround, wrap the child with the GlobalKey in a '
'Container or other harmless child.'
);
});
}
_WidgetProvider
_widgetProvider
;
_WidgetProvider
_widgetProvider
;
@override
@override
...
...
This diff is collapsed.
Click to expand it.
packages/flutter/test/widget/reparent_state_with_layout_builder_test.dart
0 → 100644
View file @
bb4a2e8b
// Copyright 2016 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/material.dart'
;
import
'package:flutter_test/flutter_test.dart'
hide
TypeMatcher
;
// This is a regression test for https://github.com/flutter/flutter/issues/5840.
class
Bar
extends
StatefulWidget
{
@override
BarState
createState
()
=>
new
BarState
();
}
class
BarState
extends
State
<
Bar
>
{
final
GlobalKey
_fooKey
=
new
GlobalKey
();
bool
_mode
=
false
;
void
trigger
()
{
setState
(()
{
_mode
=
!
_mode
;
});
}
@override
Widget
build
(
BuildContext
context
)
{
if
(
_mode
)
{
return
new
SizedBox
(
child:
new
LayoutBuilder
(
builder:
(
BuildContext
context
,
BoxConstraints
constraints
)
=>
new
StatefulCreationCounter
(
key:
_fooKey
),
),
);
}
else
{
return
new
LayoutBuilder
(
builder:
(
BuildContext
context
,
BoxConstraints
constraints
)
=>
new
StatefulCreationCounter
(
key:
_fooKey
),
);
}
}
}
class
StatefulCreationCounter
extends
StatefulWidget
{
StatefulCreationCounter
({
Key
key
})
:
super
(
key:
key
);
@override
StatefulCreationCounterState
createState
()
=>
new
StatefulCreationCounterState
();
}
class
StatefulCreationCounterState
extends
State
<
StatefulCreationCounter
>
{
static
int
creationCount
=
0
;
@override
void
initState
()
{
super
.
initState
();
creationCount
+=
1
;
}
@override
Widget
build
(
BuildContext
context
)
=>
new
Container
();
}
void
main
(
)
{
testWidgets
(
'reparent state with layout builder'
,
(
WidgetTester
tester
)
async
{
expect
(
StatefulCreationCounterState
.
creationCount
,
0
);
await
tester
.
pumpWidget
(
new
Bar
());
expect
(
StatefulCreationCounterState
.
creationCount
,
1
);
BarState
s
=
tester
.
state
/*<BarState>*/
(
find
.
byType
(
Bar
));
s
.
trigger
();
await
tester
.
pump
();
expect
(
StatefulCreationCounterState
.
creationCount
,
1
);
});
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment