Revert "Avoid calling performLayout
when only the relayout boundary is different" (#100068)
This commit is contained in:
parent
f58e8f56ef
commit
a3514c77c6
@ -1629,16 +1629,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
assert(_debugSubtreeRelayoutRootAlreadyMarkedNeedsLayout());
|
assert(_debugSubtreeRelayoutRootAlreadyMarkedNeedsLayout());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_relayoutBoundary == null) {
|
assert(_relayoutBoundary != null);
|
||||||
_needsLayout = true;
|
|
||||||
if (parent != null) {
|
|
||||||
// _relayoutBoundary is cleaned by an ancestor in RenderObject.layout.
|
|
||||||
// Conservatively mark everything dirty until it reaches the closest
|
|
||||||
// known relayout boundary.
|
|
||||||
markParentNeedsLayout();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_relayoutBoundary != this) {
|
if (_relayoutBoundary != this) {
|
||||||
markParentNeedsLayout();
|
markParentNeedsLayout();
|
||||||
} else {
|
} else {
|
||||||
@ -1692,31 +1683,16 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
void _cleanRelayoutBoundary() {
|
void _cleanRelayoutBoundary() {
|
||||||
if (_relayoutBoundary != this) {
|
if (_relayoutBoundary != this) {
|
||||||
_relayoutBoundary = null;
|
_relayoutBoundary = null;
|
||||||
|
_needsLayout = true;
|
||||||
visitChildren(_cleanChildRelayoutBoundary);
|
visitChildren(_cleanChildRelayoutBoundary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _propagateRelayoutBoundary() {
|
|
||||||
if (_relayoutBoundary == this) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final RenderObject? parentRelayoutBoundary = (parent as RenderObject?)?._relayoutBoundary;
|
|
||||||
assert(parentRelayoutBoundary != null);
|
|
||||||
if (parentRelayoutBoundary != _relayoutBoundary) {
|
|
||||||
_relayoutBoundary = parentRelayoutBoundary;
|
|
||||||
visitChildren(_propagateRelayoutBoundaryToChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reduces closure allocation for visitChildren use cases.
|
// Reduces closure allocation for visitChildren use cases.
|
||||||
static void _cleanChildRelayoutBoundary(RenderObject child) {
|
static void _cleanChildRelayoutBoundary(RenderObject child) {
|
||||||
child._cleanRelayoutBoundary();
|
child._cleanRelayoutBoundary();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _propagateRelayoutBoundaryToChild(RenderObject child) {
|
|
||||||
child._propagateRelayoutBoundary();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Bootstrap the rendering pipeline by scheduling the very first layout.
|
/// Bootstrap the rendering pipeline by scheduling the very first layout.
|
||||||
///
|
///
|
||||||
/// Requires this render object to be attached and that this render object
|
/// Requires this render object to be attached and that this render object
|
||||||
@ -1838,14 +1814,17 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
));
|
));
|
||||||
assert(!_debugDoingThisResize);
|
assert(!_debugDoingThisResize);
|
||||||
assert(!_debugDoingThisLayout);
|
assert(!_debugDoingThisLayout);
|
||||||
final bool isRelayoutBoundary = !parentUsesSize || sizedByParent || constraints.isTight || parent is! RenderObject;
|
RenderObject? relayoutBoundary;
|
||||||
final RenderObject relayoutBoundary = isRelayoutBoundary ? this : (parent! as RenderObject)._relayoutBoundary!;
|
if (!parentUsesSize || sizedByParent || constraints.isTight || parent is! RenderObject) {
|
||||||
|
relayoutBoundary = this;
|
||||||
|
} else {
|
||||||
|
relayoutBoundary = (parent! as RenderObject)._relayoutBoundary;
|
||||||
|
}
|
||||||
assert(() {
|
assert(() {
|
||||||
_debugCanParentUseSize = parentUsesSize;
|
_debugCanParentUseSize = parentUsesSize;
|
||||||
return true;
|
return true;
|
||||||
}());
|
}());
|
||||||
|
if (!_needsLayout && constraints == _constraints && relayoutBoundary == _relayoutBoundary) {
|
||||||
if (!_needsLayout && constraints == _constraints) {
|
|
||||||
assert(() {
|
assert(() {
|
||||||
// in case parentUsesSize changed since the last invocation, set size
|
// in case parentUsesSize changed since the last invocation, set size
|
||||||
// to itself, so it has the right internal debug values.
|
// to itself, so it has the right internal debug values.
|
||||||
@ -1860,11 +1839,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
return true;
|
return true;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
if (relayoutBoundary != _relayoutBoundary) {
|
|
||||||
_relayoutBoundary = relayoutBoundary;
|
|
||||||
visitChildren(_propagateRelayoutBoundaryToChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!kReleaseMode && debugProfileLayoutsEnabled)
|
if (!kReleaseMode && debugProfileLayoutsEnabled)
|
||||||
Timeline.finishSync();
|
Timeline.finishSync();
|
||||||
return;
|
return;
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
// Copyright 2014 The Flutter 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/rendering.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
testWidgets('relayout boundary change does not trigger relayout', (WidgetTester tester) async {
|
|
||||||
final RenderLayoutCount renderLayoutCount = RenderLayoutCount();
|
|
||||||
final Widget layoutCounter = Center(
|
|
||||||
key: GlobalKey(),
|
|
||||||
child: WidgetToRenderBoxAdapter(renderBox: renderLayoutCount),
|
|
||||||
);
|
|
||||||
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Center(
|
|
||||||
child: SizedBox(
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
child: Center(
|
|
||||||
child: SizedBox(
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
child: Center(
|
|
||||||
child: layoutCounter,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(renderLayoutCount.layoutCount, 1);
|
|
||||||
|
|
||||||
await tester.pumpWidget(
|
|
||||||
Center(
|
|
||||||
child: SizedBox(
|
|
||||||
width: 100,
|
|
||||||
height: 100,
|
|
||||||
child: layoutCounter,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(renderLayoutCount.layoutCount, 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// This class is needed because LayoutBuilder's RenderObject does not always
|
|
||||||
// call the builder method in its PerformLayout method.
|
|
||||||
class RenderLayoutCount extends RenderBox {
|
|
||||||
int layoutCount = 0;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void performLayout() {
|
|
||||||
layoutCount += 1;
|
|
||||||
size = constraints.biggest;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user