Skip to content

Commit d8c9ce9

Browse files
authored
Add Material 3 FloatingActionButton and FloatingActionButton variants examples (#101105)
1 parent c659a01 commit d8c9ce9

File tree

9 files changed

+302
-14
lines changed

9 files changed

+302
-14
lines changed

examples/api/lib/material/floating_action_button/floating_action_button.0.dart

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,22 @@ void main() => runApp(const MyApp());
1111
class MyApp extends StatelessWidget {
1212
const MyApp({Key? key}) : super(key: key);
1313

14-
static const String _title = 'Flutter Code Sample';
15-
1614
@override
1715
Widget build(BuildContext context) {
1816
return const MaterialApp(
19-
title: _title,
20-
home: MyStatelessWidget(),
17+
home: FabExample(),
2118
);
2219
}
2320
}
2421

25-
class MyStatelessWidget extends StatelessWidget {
26-
const MyStatelessWidget({Key? key}) : super(key: key);
22+
class FabExample extends StatelessWidget {
23+
const FabExample({Key? key}) : super(key: key);
2724

2825
@override
2926
Widget build(BuildContext context) {
3027
return Scaffold(
3128
appBar: AppBar(
32-
title: const Text('Floating Action Button'),
29+
title: const Text('FloatingActionButton Sample'),
3330
),
3431
body: const Center(child: Text('Press the button below!')),
3532
floatingActionButton: FloatingActionButton(

examples/api/lib/material/floating_action_button/floating_action_button.1.dart

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,22 @@ void main() => runApp(const MyApp());
1111
class MyApp extends StatelessWidget {
1212
const MyApp({Key? key}) : super(key: key);
1313

14-
static const String _title = 'Flutter Code Sample';
15-
1614
@override
1715
Widget build(BuildContext context) {
1816
return const MaterialApp(
19-
title: _title,
20-
home: MyStatelessWidget(),
17+
home: FabExample(),
2118
);
2219
}
2320
}
2421

25-
class MyStatelessWidget extends StatelessWidget {
26-
const MyStatelessWidget({Key? key}) : super(key: key);
22+
class FabExample extends StatelessWidget {
23+
const FabExample({Key? key}) : super(key: key);
2724

2825
@override
2926
Widget build(BuildContext context) {
3027
return Scaffold(
3128
appBar: AppBar(
32-
title: const Text('Floating Action Button Label'),
29+
title: const Text('FloatingActionButton Sample'),
3330
),
3431
body: const Center(
3532
child: Text('Press the button with a label below!'),
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flutter code sample for FloatingActionButton
6+
7+
import 'package:flutter/material.dart';
8+
9+
void main() => runApp(const MyApp());
10+
11+
class MyApp extends StatelessWidget {
12+
const MyApp({Key? key}) : super(key: key);
13+
14+
@override
15+
Widget build(BuildContext context) {
16+
return MaterialApp(
17+
theme: ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true),
18+
home: const FabExample(),
19+
);
20+
}
21+
}
22+
23+
class FabExample extends StatelessWidget {
24+
const FabExample({Key? key}) : super(key: key);
25+
26+
@override
27+
Widget build(BuildContext context) {
28+
return Scaffold(
29+
appBar: AppBar(
30+
title: const Text('FloatingActionButton Sample'),
31+
),
32+
body: const Center(child: Text('Press the button below!')),
33+
// An example of the floating action button.
34+
//
35+
// https://m3.material.io/components/floating-action-button/specs
36+
floatingActionButton: FloatingActionButton(
37+
onPressed: () {
38+
// Add your onPressed code here!
39+
},
40+
child: const Icon(Icons.add),
41+
),
42+
);
43+
}
44+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flutter code sample for FloatingActionButton
6+
7+
import 'package:flutter/material.dart';
8+
9+
void main() => runApp(const MyApp());
10+
11+
class MyApp extends StatelessWidget {
12+
const MyApp({Key? key}) : super(key: key);
13+
14+
@override
15+
Widget build(BuildContext context) {
16+
return MaterialApp(
17+
theme: ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true),
18+
home: const FabExample(),
19+
);
20+
}
21+
}
22+
23+
class FabExample extends StatelessWidget {
24+
const FabExample({Key? key}) : super(key: key);
25+
26+
@override
27+
Widget build(BuildContext context) {
28+
return Scaffold(
29+
appBar: AppBar(
30+
title: const Text('FloatingActionButton Sample'),
31+
),
32+
body: Center(
33+
child: Column(
34+
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
35+
children: <Widget>[
36+
Row(
37+
mainAxisAlignment: MainAxisAlignment.center,
38+
children: <Widget>[
39+
const Text('Small'),
40+
const SizedBox(width: 16),
41+
// An example of the small floating action button.
42+
//
43+
// https://m3.material.io/components/floating-action-button/specs#669a1be8-7271-48cb-a74d-dd502d73bda4
44+
FloatingActionButton.small(
45+
onPressed: () {
46+
// Add your onPressed code here!
47+
},
48+
child: const Icon(Icons.add),
49+
),
50+
],
51+
),
52+
Row(
53+
mainAxisAlignment: MainAxisAlignment.center,
54+
children: <Widget>[
55+
const Text('Regular'),
56+
const SizedBox(width: 16),
57+
// An example of the regular floating action button.
58+
//
59+
// https://m3.material.io/components/floating-action-button/specs#71504201-7bd1-423d-8bb7-07e0291743e5
60+
FloatingActionButton(
61+
onPressed: () {
62+
// Add your onPressed code here!
63+
},
64+
child: const Icon(Icons.add),
65+
),
66+
],
67+
),
68+
Row(
69+
mainAxisAlignment: MainAxisAlignment.center,
70+
children: <Widget>[
71+
const Text('Large'),
72+
const SizedBox(width: 16),
73+
// An example of the large floating action button.
74+
//
75+
// https://m3.material.io/components/floating-action-button/specs#9d7d3d6a-bab7-47cb-be32-5596fbd660fe
76+
FloatingActionButton.large(
77+
onPressed: () {
78+
// Add your onPressed code here!
79+
},
80+
child: const Icon(Icons.add),
81+
),
82+
],
83+
),
84+
Row(
85+
mainAxisAlignment: MainAxisAlignment.center,
86+
children: <Widget>[
87+
const Text('Extended'),
88+
const SizedBox(width: 16),
89+
// An example of the extended floating action button.
90+
//
91+
// https://m3.material.io/components/extended-fab/specs#686cb8af-87c9-48e8-a3e1-db9da6f6c69b
92+
FloatingActionButton.extended(
93+
onPressed: () {
94+
// Add your onPressed code here!
95+
},
96+
label: const Text('Add'),
97+
icon: const Icon(Icons.add),
98+
),
99+
],
100+
),
101+
],
102+
),
103+
),
104+
);
105+
}
106+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter_api_samples/material/floating_action_button/floating_action_button.0.dart'
7+
as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('FloatingActionButton', (WidgetTester tester) async {
12+
await tester.pumpWidget(
13+
const example.MyApp(),
14+
);
15+
16+
expect(find.byType(FloatingActionButton), findsOneWidget);
17+
expect(find.byIcon(Icons.navigation), findsOneWidget);
18+
19+
final Finder materialButtonFinder = find.byType(RawMaterialButton);
20+
RawMaterialButton getRawMaterialButtonWidget() {
21+
return tester.widget<RawMaterialButton>(materialButtonFinder);
22+
}
23+
expect(getRawMaterialButtonWidget().fillColor, Colors.green);
24+
expect(getRawMaterialButtonWidget().shape, const CircleBorder());
25+
});
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter_api_samples/material/floating_action_button/floating_action_button.1.dart'
7+
as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('FloatingActionButton.extended', (WidgetTester tester) async {
12+
await tester.pumpWidget(
13+
const example.MyApp(),
14+
);
15+
16+
expect(find.byType(FloatingActionButton), findsOneWidget);
17+
expect(find.text('Approve'), findsOneWidget);
18+
expect(find.byIcon(Icons.thumb_up), findsOneWidget);
19+
20+
final Finder materialButtonFinder = find.byType(RawMaterialButton);
21+
RawMaterialButton getRawMaterialButtonWidget() {
22+
return tester.widget<RawMaterialButton>(materialButtonFinder);
23+
}
24+
expect(getRawMaterialButtonWidget().fillColor, Colors.pink);
25+
expect(getRawMaterialButtonWidget().shape, const StadiumBorder());
26+
});
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter_api_samples/material/floating_action_button/floating_action_button.2.dart'
7+
as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('FloatingActionButton - Material 3', (WidgetTester tester) async {
12+
RawMaterialButton getRawMaterialButtonWidget(Finder finder) {
13+
return tester.widget<RawMaterialButton>(finder);
14+
}
15+
await tester.pumpWidget(
16+
const example.MyApp(),
17+
);
18+
19+
expect(find.byType(FloatingActionButton), findsOneWidget);
20+
expect(find.byIcon(Icons.add), findsOneWidget);
21+
22+
final ThemeData theme = ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true);
23+
final Finder materialButtonFinder = find.byType(RawMaterialButton);
24+
expect(getRawMaterialButtonWidget(materialButtonFinder).fillColor, theme.colorScheme.primaryContainer);
25+
expect(getRawMaterialButtonWidget(materialButtonFinder).shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)));
26+
});
27+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter_api_samples/material/floating_action_button/floating_action_button.3.dart'
7+
as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('FloatingActionButton variants', (WidgetTester tester) async {
12+
RawMaterialButton getRawMaterialButtonWidget(Finder finder) {
13+
return tester.widget<RawMaterialButton>(finder);
14+
}
15+
16+
await tester.pumpWidget(
17+
const example.MyApp(),
18+
);
19+
20+
final ThemeData theme = ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true);
21+
22+
expect(find.byType(FloatingActionButton), findsNWidgets(4));
23+
expect(find.byIcon(Icons.add), findsNWidgets(4));
24+
25+
final Finder smallFabMaterialButton = find.byType(RawMaterialButton).at(0);
26+
final RenderBox smallFabRenderBox = tester.renderObject(smallFabMaterialButton);
27+
expect(smallFabRenderBox.size, const Size(48.0, 48.0));
28+
expect(getRawMaterialButtonWidget(smallFabMaterialButton).fillColor, theme.colorScheme.primaryContainer);
29+
expect(getRawMaterialButtonWidget(smallFabMaterialButton).shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)));
30+
31+
final Finder regularFABMaterialButton = find.byType(RawMaterialButton).at(1);
32+
final RenderBox regularFABRenderBox = tester.renderObject(regularFABMaterialButton);
33+
expect(regularFABRenderBox.size, const Size(56.0, 56.0));
34+
expect(getRawMaterialButtonWidget(regularFABMaterialButton).fillColor, theme.colorScheme.primaryContainer);
35+
expect(getRawMaterialButtonWidget(regularFABMaterialButton).shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)));
36+
37+
final Finder largeFABMaterialButton = find.byType(RawMaterialButton).at(2);
38+
final RenderBox largeFABRenderBox = tester.renderObject(largeFABMaterialButton);
39+
expect(largeFABRenderBox.size, const Size(96.0, 96.0));
40+
expect(getRawMaterialButtonWidget(largeFABMaterialButton).fillColor, theme.colorScheme.primaryContainer);
41+
expect(getRawMaterialButtonWidget(largeFABMaterialButton).shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(28.0)));
42+
43+
final Finder extendedFABMaterialButton = find.byType(RawMaterialButton).at(3);
44+
final RenderBox extendedFABRenderBox = tester.renderObject(extendedFABMaterialButton);
45+
expect(extendedFABRenderBox.size, const Size(111.0, 56.0));
46+
expect(getRawMaterialButtonWidget(extendedFABMaterialButton).fillColor, theme.colorScheme.primaryContainer);
47+
expect(getRawMaterialButtonWidget(extendedFABMaterialButton).shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)));
48+
});
49+
}

packages/flutter/lib/src/material/floating_action_button.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,21 @@ enum _FloatingActionButtonType {
6969
/// ** See code in examples/api/lib/material/floating_action_button/floating_action_button.1.dart **
7070
/// {@end-tool}
7171
///
72+
/// Material Design 3 introduced new types of floating action buttons.
73+
/// {@tool dartpad}
74+
/// This sample shows the creation of [FloatingActionButton] widget in the typical location in a Scaffold,
75+
/// as described in: https://m3.material.io/components/floating-action-button/overview
76+
///
77+
/// ** See code in examples/api/lib/material/floating_action_button/floating_action_button.2.dart **
78+
/// {@end-tool}
79+
///
80+
/// {@tool dartpad}
81+
/// This sample shows the creation of all the variants of [FloatingActionButton] widget as
82+
/// described in: https://m3.material.io/components/floating-action-button/overview
83+
///
84+
/// ** See code in examples/api/lib/material/floating_action_button/floating_action_button.3.dart **
85+
/// {@end-tool}
86+
///
7287
/// See also:
7388
///
7489
/// * [Scaffold], in which floating action buttons typically live.

0 commit comments

Comments
 (0)