Unverified Commit 3f5bd7d8 authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Add Material 3 `AppBar` example (#102823)

parent 348a2b4f
......@@ -6,24 +6,21 @@
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
void main() => runApp(const AppBarApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
class AppBarApp extends StatelessWidget {
const AppBarApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatelessWidget(),
home: AppBarExample(),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({super.key});
class AppBarExample extends StatelessWidget {
const AppBarExample({super.key});
@override
Widget build(BuildContext context) {
......
......@@ -6,43 +6,120 @@
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
final List<int> _items = List<int>.generate(51, (int index) => index);
class MyApp extends StatelessWidget {
const MyApp({super.key});
void main() => runApp(const AppBarApp());
static const String _title = 'Flutter Code Sample';
class AppBarApp extends StatelessWidget {
const AppBarApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatelessWidget(),
return MaterialApp(
theme: ThemeData(
colorSchemeSeed: const Color(0xff6750a4),
useMaterial3: true,
),
home: const AppBarExample(),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({super.key});
class AppBarExample extends StatefulWidget {
const AppBarExample({super.key});
@override
State<AppBarExample> createState() => _AppBarExampleState();
}
class _AppBarExampleState extends State<AppBarExample> {
bool shadowColor = false;
double? scrolledUnderElevation;
@override
Widget build(BuildContext context) {
final ButtonStyle style =
TextButton.styleFrom(primary: Theme.of(context).colorScheme.onPrimary);
final ColorScheme colorScheme = Theme.of(context).colorScheme;
final Color oddItemColor = colorScheme.primary.withOpacity(0.05);
final Color evenItemColor = colorScheme.primary.withOpacity(0.15);
return Scaffold(
appBar: AppBar(
actions: <Widget>[
TextButton(
style: style,
onPressed: () {},
child: const Text('Action 1'),
),
TextButton(
style: style,
onPressed: () {},
child: const Text('Action 2'),
title: const Text('AppBar Demo'),
scrolledUnderElevation: scrolledUnderElevation,
shadowColor: shadowColor ? Theme.of(context).colorScheme.shadow : null,
),
body: GridView.builder(
shrinkWrap: true,
itemCount: _items.length,
padding: const EdgeInsets.all(8.0),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 2.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
),
itemBuilder: (BuildContext context, int index) {
if (index == 0) {
return Center(
child: Text(
'Scroll to see the Appbar in effect.',
style: Theme.of(context).textTheme.labelLarge,
textAlign: TextAlign.center,
),
);
}
return Container(
alignment: Alignment.center,
// tileColor: _items[index].isOdd ? oddItemColor : evenItemColor,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: _items[index].isOdd ? oddItemColor : evenItemColor,
),
child: Text('Item $index'),
);
},
),
bottomNavigationBar: BottomAppBar(
child: Padding(
padding: const EdgeInsets.all(8),
child: OverflowBar(
overflowAlignment: OverflowBarAlignment.center,
alignment: MainAxisAlignment.center,
overflowSpacing: 5.0,
children: <Widget>[
ElevatedButton.icon(
onPressed: () {
setState(() {
shadowColor = !shadowColor;
});
},
icon: Icon(
shadowColor ? Icons.visibility_off : Icons.visibility,
),
label: const Text('shadow color'),
),
const SizedBox(width: 5),
ElevatedButton.icon(
onPressed: () {
if (scrolledUnderElevation == null) {
setState(() {
// Default elevation is 3.0, increment by 1.0.
scrolledUnderElevation = 4.0;
});
} else {
setState(() {
scrolledUnderElevation = scrolledUnderElevation! + 1.0;
});
}
},
icon: const Icon(Icons.add),
label: Text(
'scrolledUnderElevation: ${scrolledUnderElevation ?? 'default'}',
),
),
],
),
],
),
),
);
}
......
// 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';
void main() => runApp(const AppBarApp());
class AppBarApp extends StatelessWidget {
const AppBarApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: AppBarExample(),
);
}
}
class AppBarExample extends StatelessWidget {
const AppBarExample({super.key});
@override
Widget build(BuildContext context) {
final ButtonStyle style = TextButton.styleFrom(
primary: Theme.of(context).colorScheme.onPrimary,
);
return Scaffold(
appBar: AppBar(
actions: <Widget>[
TextButton(
style: style,
onPressed: () {},
child: const Text('Action 1'),
),
TextButton(
style: style,
onPressed: () {},
child: const Text('Action 2'),
),
],
),
);
}
}
......@@ -6,30 +6,27 @@
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
void main() => runApp(const AppBarApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
class AppBarApp extends StatelessWidget {
const AppBarApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatefulWidget(),
home: SliverAppBarExample(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
class SliverAppBarExample extends StatefulWidget {
const SliverAppBarExample({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
State<SliverAppBarExample> createState() => _SliverAppBarExampleState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
class _SliverAppBarExampleState extends State<SliverAppBarExample> {
bool _pinned = true;
bool _snap = false;
bool _floating = false;
......
// 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.0.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Appbar updates on navigation', (WidgetTester tester) async {
await tester.pumpWidget(
const example.AppBarApp(),
);
expect(find.widgetWithText(AppBar, 'AppBar Demo'), findsOneWidget);
expect(find.text('This is the home page'), findsOneWidget);
await tester.tap(find.byIcon(Icons.navigate_next));
await tester.pumpAndSettle();
expect(find.widgetWithText(AppBar, 'Next page'), findsOneWidget);
expect(find.text('This is the next page'), findsOneWidget);
});
}
// 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.1.dart' as example;
import 'package:flutter_test/flutter_test.dart';
const Offset _kOffset = Offset(0.0, -100.0);
void main() {
testWidgets('Appbar Material 3 test', (WidgetTester tester) async {
await tester.pumpWidget(
const example.AppBarApp()
);
expect(find.widgetWithText(AppBar, 'AppBar Demo'), findsOneWidget);
Material appbarMaterial = _getAppBarMaterial(tester);
expect(appbarMaterial.shadowColor, null);
expect(appbarMaterial.elevation, 0);
await tester.drag(find.text('Item 4'), _kOffset, touchSlopY: 0, warnIfMissed: false);
await tester.pump();
await tester.pump(const Duration(milliseconds: 500));
await tester.tap(find.text('shadow color'));
await tester.pumpAndSettle();
appbarMaterial = _getAppBarMaterial(tester);
expect(appbarMaterial.shadowColor, Colors.black);
expect(appbarMaterial.elevation, 3.0);
await tester.tap(find.text('scrolledUnderElevation: default'));
await tester.pumpAndSettle();
appbarMaterial = _getAppBarMaterial(tester);
expect(appbarMaterial.shadowColor, Colors.black);
expect(appbarMaterial.elevation, 4.0);
await tester.tap(find.text('scrolledUnderElevation: 4.0'));
await tester.pumpAndSettle();
appbarMaterial = _getAppBarMaterial(tester);
expect(appbarMaterial.shadowColor, Colors.black);
expect(appbarMaterial.elevation, 5.0);
});
}
Material _getAppBarMaterial(WidgetTester tester) {
return tester.widget<Material>(
find.descendant(
of: find.byType(AppBar),
matching: find.byType(Material),
),
);
}
// 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.2.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Appbar and actions', (WidgetTester tester) async {
await tester.pumpWidget(
const example.AppBarApp(),
);
expect(find.byType(AppBar), findsOneWidget);
expect(find.widgetWithText(TextButton, 'Action 1'), findsOneWidget);
expect(find.widgetWithText(TextButton, 'Action 2'), findsOneWidget);
});
}
// 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/sliver_app_bar.1.dart' as example;
import 'package:flutter_test/flutter_test.dart';
const Offset _kOffset = Offset(0.0, -200.0);
void main() {
testWidgets('SliverAppbar can be pinned', (WidgetTester tester) async {
await tester.pumpWidget(
const example.AppBarApp(),
);
expect(find.widgetWithText(SliverAppBar, 'SliverAppBar'), findsOneWidget);
expect(tester.getBottomLeft(find.text('SliverAppBar')).dy, 144.0);
await tester.drag(find.text('0'), _kOffset, touchSlopY: 0, warnIfMissed: false);
await tester.pump();
await tester.pump(const Duration(milliseconds: 500));
expect(tester.getBottomLeft(find.text('SliverAppBar')).dy, 40.0);
});
}
......@@ -107,6 +107,15 @@ class _PreferredAppBarSize extends Size {
/// ** See code in examples/api/lib/material/app_bar/app_bar.0.dart **
/// {@end-tool}
///
/// Material Design 3 introduced new types of app bar.
/// {@tool dartpad}
/// This sample shows the creation of an [AppBar] widget with the [shadowColor] and
/// [scrolledUnderElevation] properties set, as described in:
/// https://m3.material.io/components/top-app-bar/overview
///
/// ** See code in examples/api/lib/material/app_bar/app_bar.1.dart **
/// {@end-tool}
///
/// ## Troubleshooting
///
/// ### Why don't my TextButton actions appear?
......@@ -125,9 +134,10 @@ class _PreferredAppBarSize extends Size {
/// [TextButton.style]:
///
/// {@tool dartpad}
/// This sample shows an [AppBar] with two action buttons with their primary
/// color set to [ColorScheme.onPrimary].
///
///
/// ** See code in examples/api/lib/material/app_bar/app_bar.1.dart **
/// ** See code in examples/api/lib/material/app_bar/app_bar.2.dart **
/// {@end-tool}
///
/// See also:
......
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