Skip to content

Commit

Permalink
Add Material 3 AppBar example (#102823)
Browse files Browse the repository at this point in the history
  • Loading branch information
TahaTesser authored May 19, 2022
1 parent 348a2b4 commit 3f5bd7d
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 44 deletions.
15 changes: 6 additions & 9 deletions examples/api/lib/material/app_bar/app_bar.0.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
121 changes: 99 additions & 22 deletions examples/api/lib/material/app_bar/app_bar.1.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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'}',
),
),
],
),
],
),
),
);
}
Expand Down
47 changes: 47 additions & 0 deletions examples/api/lib/material/app_bar/app_bar.2.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 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'),
),
],
),
);
}
}
19 changes: 8 additions & 11 deletions examples/api/lib/material/app_bar/sliver_app_bar.1.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
24 changes: 24 additions & 0 deletions examples/api/test/material/appbar/app_bar.0_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// 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);
});
}
55 changes: 55 additions & 0 deletions examples/api/test/material/appbar/app_bar.1_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// 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),
),
);
}
19 changes: 19 additions & 0 deletions examples/api/test/material/appbar/app_bar.2_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// 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);
});
}
25 changes: 25 additions & 0 deletions examples/api/test/material/appbar/sliver_app_bar.1_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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);
});
}
Loading

0 comments on commit 3f5bd7d

Please sign in to comment.