From c422d280ab3e38c02c8167d8c0fee47d68fee62e Mon Sep 17 00:00:00 2001 From: Taha Tesser Date: Fri, 15 Jul 2022 12:40:06 +0300 Subject: [PATCH] Add an example for `AppBar.notificationPredicate` (#106018) --- .../api/lib/material/app_bar/app_bar.3.dart | 112 ++++++++++++++++++ .../test/material/appbar/app_bar.3_test.dart | 31 +++++ .../flutter/lib/src/material/app_bar.dart | 8 ++ 3 files changed, 151 insertions(+) create mode 100644 examples/api/lib/material/app_bar/app_bar.3.dart create mode 100644 examples/api/test/material/appbar/app_bar.3_test.dart diff --git a/examples/api/lib/material/app_bar/app_bar.3.dart b/examples/api/lib/material/app_bar/app_bar.3.dart new file mode 100644 index 0000000000..f312a3d9c5 --- /dev/null +++ b/examples/api/lib/material/app_bar/app_bar.3.dart @@ -0,0 +1,112 @@ +// 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. + +// Flutter code sample for AppBar + +import 'package:flutter/material.dart'; + +List titles = [ + 'Cloud', + 'Beach', + 'Sunny', +]; + +void main() => runApp(const AppBarApp()); + +class AppBarApp extends StatelessWidget { + const AppBarApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true), + home: const AppBarExample(), + ); + } +} + +class AppBarExample extends StatelessWidget { + const AppBarExample({super.key}); + + @override + Widget build(BuildContext context) { + final ColorScheme colorScheme = Theme.of(context).colorScheme; + final Color oddItemColor = colorScheme.primary.withOpacity(0.05); + final Color evenItemColor = colorScheme.primary.withOpacity(0.15); + const int tabsCount = 3; + + return DefaultTabController( + initialIndex: 1, + length: tabsCount, + child: Scaffold( + appBar: AppBar( + title: const Text('AppBar Sample'), + // This check specifies which nested Scrollable's scroll notification + // should be listened to. + // + // When `ThemeData.useMaterial3` is true and scroll view has + // scrolled underneath the app bar, this updates the app bar + // background color and elevation. + // + // This sets `notification.depth == 1` to listen to the scroll + // notification from the nested `ListView.builder`. + notificationPredicate: (ScrollNotification notification) { + return notification.depth == 1; + }, + // The elevation value of the app bar when scroll view has + // scrolled underneath the app bar. + scrolledUnderElevation: 4.0, + shadowColor: Theme.of(context).shadowColor, + bottom: TabBar( + tabs: [ + Tab( + icon: const Icon(Icons.cloud_outlined), + text: titles[0], + ), + Tab( + icon: const Icon(Icons.beach_access_sharp), + text: titles[1], + ), + Tab( + icon: const Icon(Icons.brightness_5_sharp), + text: titles[2], + ), + ], + ), + ), + body: TabBarView( + children: [ + ListView.builder( + itemCount: 25, + itemBuilder: (BuildContext context, int index) { + return ListTile( + tileColor: index.isOdd ? oddItemColor : evenItemColor, + title: Text('${titles[0]} $index'), + ); + }, + ), + ListView.builder( + itemCount: 25, + itemBuilder: (BuildContext context, int index) { + return ListTile( + tileColor: index.isOdd ? oddItemColor : evenItemColor, + title: Text('${titles[1]} $index'), + ); + }, + ), + ListView.builder( + itemCount: 25, + itemBuilder: (BuildContext context, int index) { + return ListTile( + tileColor: index.isOdd ? oddItemColor : evenItemColor, + title: Text('${titles[2]} $index'), + ); + }, + ), + ], + ), + ), + ); + } +} diff --git a/examples/api/test/material/appbar/app_bar.3_test.dart b/examples/api/test/material/appbar/app_bar.3_test.dart new file mode 100644 index 0000000000..b8fb9b570f --- /dev/null +++ b/examples/api/test/material/appbar/app_bar.3_test.dart @@ -0,0 +1,31 @@ +// 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/material.dart'; +import 'package:flutter_api_samples/material/app_bar/app_bar.3.dart' as example; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets( + 'AppBar elevates when nested scroll view is scrolled underneath the AppBar', + (WidgetTester tester) async { + Material getMaterial() => tester.widget(find.descendant( + of: find.byType(AppBar), + matching: find.byType(Material), + )); + + await tester.pumpWidget( + const example.AppBarApp(), + ); + + // Starts with the base elevation. + expect(getMaterial().elevation, 0.0); + + await tester.fling(find.text('Beach 3'), const Offset(0.0, -600.0), 2000.0); + await tester.pumpAndSettle(); + + // After scrolling it should be the scrolledUnderElevation. + expect(getMaterial().elevation, 4.0); + }); +} diff --git a/packages/flutter/lib/src/material/app_bar.dart b/packages/flutter/lib/src/material/app_bar.dart index 3d4aae05a8..bdf23f9163 100644 --- a/packages/flutter/lib/src/material/app_bar.dart +++ b/packages/flutter/lib/src/material/app_bar.dart @@ -140,6 +140,14 @@ class _PreferredAppBarSize extends Size { /// ** See code in examples/api/lib/material/app_bar/app_bar.2.dart ** /// {@end-tool} /// +/// {@tool dartpad} +/// This example shows how to listen to a nested Scrollable's scroll notification +/// in a nested scroll view using the [notificationPredicate] property and use it +/// to make [scrolledUnderElevation] take effect. +/// +/// ** See code in examples/api/lib/material/app_bar/app_bar.3.dart ** +/// {@end-tool} +/// /// See also: /// /// * [Scaffold], which displays the [AppBar] in its [Scaffold.appBar] slot.