Unverified Commit 7120dab5 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Don't crash if pinned & floating AppBar has less than minExtent remainingPaintExtent (#25048)

Fixes https://github.com/flutter/flutter/issues/21887
parent b023a574
......@@ -515,13 +515,15 @@ abstract class RenderSliverFloatingPinnedPersistentHeader extends RenderSliverFl
@override
double updateGeometry() {
final double minExtent = this.minExtent;
final double minAllowedExtent = constraints.remainingPaintExtent > minExtent ? minExtent : constraints.remainingPaintExtent;
final double maxExtent = this.maxExtent;
final double paintExtent = maxExtent - _effectiveScrollOffset;
final double clampedPaintExtent = paintExtent.clamp(minAllowedExtent, constraints.remainingPaintExtent);
final double layoutExtent = maxExtent - constraints.scrollOffset;
geometry = SliverGeometry(
scrollExtent: maxExtent,
paintExtent: paintExtent.clamp(minExtent, constraints.remainingPaintExtent),
layoutExtent: layoutExtent.clamp(0.0, constraints.remainingPaintExtent - minExtent),
paintExtent: clampedPaintExtent,
layoutExtent: layoutExtent.clamp(0.0, clampedPaintExtent),
maxPaintExtent: maxExtent,
maxScrollObstructionExtent: maxExtent,
hasVisualOverflow: true, // Conservatively say we do have overflow to avoid complexity.
......
......@@ -2,6 +2,7 @@
// 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_test/flutter_test.dart';
import 'package:flutter/material.dart';
......@@ -66,4 +67,49 @@ void main() {
// we've scrolled that up by 600.0, meaning it's at that minus 600 now:
expect(tester.getTopLeft(find.text('E')), Offset(0.0, 200.0 + 56.0 + cSize.height * 2.0 + 500.0 - 600.0));
});
testWidgets('Does not crash when there is less than minExtent remainingPaintExtent', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/21887.
final ScrollController controller = ScrollController();
const double availableHeight = 50.0;
await tester.pumpWidget(
MaterialApp(
home: Center(
child: Container(
height: availableHeight,
color: Colors.green,
child: CustomScrollView(
controller: controller,
slivers: <Widget>[
const SliverAppBar(
pinned: true,
floating: true,
expandedHeight: 120.0,
),
SliverList(
delegate: SliverChildListDelegate(List<Widget>.generate(20, (int i) {
return Container(
child: Text('Tile $i'),
height: 100.0,
);
})),
)
],
),
),
),
),
);
final RenderSliverFloatingPinnedPersistentHeader render = tester.renderObject(find.byType(SliverAppBar));
expect(render.minExtent, greaterThan(availableHeight)); // Precondition
expect(render.geometry.scrollExtent, 120.0);
expect(render.geometry.paintExtent, availableHeight);
expect(render.geometry.layoutExtent, availableHeight);
controller.jumpTo(200.0);
await tester.pumpAndSettle();
expect(render.geometry.scrollExtent, 120.0);
expect(render.geometry.paintExtent, availableHeight);
expect(render.geometry.layoutExtent, 0.0);
});
}
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