Fix SliverAppBar title opacity and test all cases (#26021)
diff --git a/packages/flutter/lib/src/material/app_bar.dart b/packages/flutter/lib/src/material/app_bar.dart
index ed3fbad..c4f160e6 100644
--- a/packages/flutter/lib/src/material/app_bar.dart
+++ b/packages/flutter/lib/src/material/app_bar.dart
@@ -650,8 +650,22 @@
@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
final double visibleMainHeight = maxExtent - shrinkOffset - topPadding;
- final double toolbarOpacity = pinned ? 1.0
- : ((visibleMainHeight - _bottomHeight) / kToolbarHeight).clamp(0.0, 1.0);
+
+ // Truth table for `toolbarOpacity`:
+ // pinned | floating | bottom != null || opacity
+ // ----------------------------------------------
+ // 0 | 0 | 0 || fade
+ // 0 | 0 | 1 || fade
+ // 0 | 1 | 0 || fade
+ // 0 | 1 | 1 || fade
+ // 1 | 0 | 0 || 1.0
+ // 1 | 0 | 1 || 1.0
+ // 1 | 1 | 0 || 1.0
+ // 1 | 1 | 1 || fade
+ final double toolbarOpacity = !pinned || (floating && bottom != null)
+ ? ((visibleMainHeight - _bottomHeight) / kToolbarHeight).clamp(0.0, 1.0)
+ : 1.0;
+
final Widget appBar = FlexibleSpaceBar.createSettings(
minExtent: minExtent,
maxExtent: maxExtent,
diff --git a/packages/flutter/test/widgets/sliver_appbar_opacity.dart b/packages/flutter/test/widgets/sliver_appbar_opacity.dart
new file mode 100644
index 0000000..385a14d
--- /dev/null
+++ b/packages/flutter/test/widgets/sliver_appbar_opacity.dart
@@ -0,0 +1,205 @@
+// Copyright 2019 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/rendering.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:flutter/material.dart';
+
+void main() {
+ testWidgets('!pinned && !floating && !bottom ==> fade opactiy', (WidgetTester tester) async {
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(
+ _TestWidget(
+ pinned: false,
+ floating: false,
+ bottom: false,
+ controller: controller,
+ )
+ );
+
+ final RenderParagraph render = tester.renderObject(find.text('Hallo Welt!!1'));
+ expect(render.text.style.color.opacity, 1.0);
+
+ controller.jumpTo(200.0);
+ await tester.pumpAndSettle();
+ expect(render.text.style.color.opacity, 0.0);
+ });
+
+ testWidgets('!pinned && !floating && bottom ==> fade opactiy', (WidgetTester tester) async {
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(
+ _TestWidget(
+ pinned: false,
+ floating: false,
+ bottom: true,
+ controller: controller,
+ )
+ );
+
+ final RenderParagraph render = tester.renderObject(find.text('Hallo Welt!!1'));
+ expect(render.text.style.color.opacity, 1.0);
+
+ controller.jumpTo(200.0);
+ await tester.pumpAndSettle();
+ expect(render.text.style.color.opacity, 0.0);
+ });
+
+ testWidgets('!pinned && floating && !bottom ==> fade opactiy', (WidgetTester tester) async {
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(
+ _TestWidget(
+ pinned: false,
+ floating: true,
+ bottom: false,
+ controller: controller,
+ )
+ );
+
+ final RenderParagraph render = tester.renderObject(find.text('Hallo Welt!!1'));
+ expect(render.text.style.color.opacity, 1.0);
+
+ controller.jumpTo(200.0);
+ await tester.pumpAndSettle();
+ expect(render.text.style.color.opacity, 0.0);
+ });
+
+ testWidgets('!pinned && floating && bottom ==> fade opactiy', (WidgetTester tester) async {
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(
+ _TestWidget(
+ pinned: false,
+ floating: true,
+ bottom: true,
+ controller: controller,
+ )
+ );
+
+ final RenderParagraph render = tester.renderObject(find.text('Hallo Welt!!1'));
+ expect(render.text.style.color.opacity, 1.0);
+
+ controller.jumpTo(200.0);
+ await tester.pumpAndSettle();
+ expect(render.text.style.color.opacity, 0.0);
+ });
+
+ testWidgets('pinned && !floating && !bottom ==> 1.0 opacity', (WidgetTester tester) async {
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(
+ _TestWidget(
+ pinned: true,
+ floating: false,
+ bottom: false,
+ controller: controller,
+ )
+ );
+
+ final RenderParagraph render = tester.renderObject(find.text('Hallo Welt!!1'));
+ expect(render.text.style.color.opacity, 1.0);
+
+ controller.jumpTo(200.0);
+ await tester.pumpAndSettle();
+ expect(render.text.style.color.opacity, 1.0);
+ });
+
+ testWidgets('pinned && !floating && bottom ==> 1.0 opacity', (WidgetTester tester) async {
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(
+ _TestWidget(
+ pinned: true,
+ floating: false,
+ bottom: true,
+ controller: controller,
+ )
+ );
+
+ final RenderParagraph render = tester.renderObject(find.text('Hallo Welt!!1'));
+ expect(render.text.style.color.opacity, 1.0);
+
+ controller.jumpTo(200.0);
+ await tester.pumpAndSettle();
+ expect(render.text.style.color.opacity, 1.0);
+ });
+
+ testWidgets('pinned && floating && !bottom ==> 1.0 opacity', (WidgetTester tester) async {
+ // Regression test for https://github.com/flutter/flutter/issues/25000.
+
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(
+ _TestWidget(
+ pinned: true,
+ floating: true,
+ bottom: false,
+ controller: controller,
+ )
+ );
+
+ final RenderParagraph render = tester.renderObject(find.text('Hallo Welt!!1'));
+ expect(render.text.style.color.opacity, 1.0);
+
+ controller.jumpTo(200.0);
+ await tester.pumpAndSettle();
+ expect(render.text.style.color.opacity, 1.0);
+ });
+
+ testWidgets('pinned && floating && bottom ==> fade opactiy', (WidgetTester tester) async {
+ // Regression test for https://github.com/flutter/flutter/issues/25993.
+
+ final ScrollController controller = ScrollController();
+ await tester.pumpWidget(
+ _TestWidget(
+ pinned: true,
+ floating: true,
+ bottom: true,
+ controller: controller,
+ )
+ );
+
+ final RenderParagraph render = tester.renderObject(find.text('Hallo Welt!!1'));
+ expect(render.text.style.color.opacity, 1.0);
+
+ controller.jumpTo(200.0);
+ await tester.pumpAndSettle();
+ expect(render.text.style.color.opacity, 0.0);
+ });
+}
+
+class _TestWidget extends StatelessWidget {
+
+ const _TestWidget({this.pinned, this.floating, this.bottom, this.controller,});
+
+ final bool pinned;
+ final bool floating;
+ final bool bottom;
+ final ScrollController controller;
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ home: CustomScrollView(
+ controller: controller,
+ slivers: <Widget>[
+ SliverAppBar(
+ pinned: pinned,
+ floating: floating,
+ expandedHeight: 120.0,
+ title: const Text('Hallo Welt!!1'),
+ bottom: !bottom ? null : PreferredSize(
+ preferredSize: const Size.fromHeight(35.0),
+ child: Container(),
+ ),
+ ),
+ SliverList(
+ delegate: SliverChildListDelegate(List<Widget>.generate(20, (int i) {
+ return Container(
+ child: Text('Tile $i'),
+ height: 100.0,
+ );
+ })),
+ )
+ ],
+ ),
+ );
+ }
+
+}
diff --git a/packages/flutter/test/widgets/slivers_appbar_floating_pinned_test.dart b/packages/flutter/test/widgets/slivers_appbar_floating_pinned_test.dart
index 3ee0986..69614fe 100644
--- a/packages/flutter/test/widgets/slivers_appbar_floating_pinned_test.dart
+++ b/packages/flutter/test/widgets/slivers_appbar_floating_pinned_test.dart
@@ -112,40 +112,4 @@
expect(render.geometry.paintExtent, availableHeight);
expect(render.geometry.layoutExtent, 0.0);
});
-
- testWidgets('Text does not dissapear when scrolled up', (WidgetTester tester) async {
- // Regression test for https://github.com/flutter/flutter/issues/25000.
-
- final ScrollController controller = ScrollController();
- await tester.pumpWidget(
- MaterialApp(
- home: CustomScrollView(
- controller: controller,
- slivers: <Widget>[
- const SliverAppBar(
- pinned: true,
- floating: true,
- expandedHeight: 120.0,
- title: Text('Hallo Welt!!1'),
- ),
- SliverList(
- delegate: SliverChildListDelegate(List<Widget>.generate(20, (int i) {
- return Container(
- child: Text('Tile $i'),
- height: 100.0,
- );
- })),
- )
- ],
- ),
- ),
- );
-
- final RenderParagraph render = tester.renderObject(find.text('Hallo Welt!!1'));
- expect(render.text.style.color.opacity, 1.0);
-
- controller.jumpTo(200.0);
- await tester.pumpAndSettle();
- expect(render.text.style.color.opacity, 1.0);
- });
}