Skip to content

Commit 6899245

Browse files
authored
Updated Material 3 Slider Samples (#159795)
Fixes [Update `Slider` samples for updated Material 3 Slider spec](flutter/flutter#159794) ### Description This updates Slider sample to include toggle to opt in to the updated Material 3 appearance . Remove redundant sample an asset diagram. ### Preview <img width="840" alt="Screenshot 2024-12-04 at 16 03 47" src="https://github.com/user-attachments/assets/b6db9efe-8416-460e-a745-bdf37c97ed61"> ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent a6d3bb5 commit 6899245

File tree

7 files changed

+126
-159
lines changed

7 files changed

+126
-159
lines changed

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

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
import 'package:flutter/material.dart';
66

77
/// Flutter code sample for [Slider].
8+
/// set to false.
89
9-
void main() => runApp(const SliderApp());
10+
void main() => runApp(const SliderExampleApp());
1011

11-
class SliderApp extends StatelessWidget {
12-
const SliderApp({super.key});
12+
class SliderExampleApp extends StatelessWidget {
13+
const SliderExampleApp({super.key});
1314

1415
@override
1516
Widget build(BuildContext context) {
@@ -28,21 +29,51 @@ class SliderExample extends StatefulWidget {
2829

2930
class _SliderExampleState extends State<SliderExample> {
3031
double _currentSliderValue = 20;
32+
double _currentDiscreteSliderValue = 60;
33+
bool year2023 = true;
3134

3235
@override
3336
Widget build(BuildContext context) {
3437
return Scaffold(
3538
appBar: AppBar(title: const Text('Slider')),
36-
body: Slider(
37-
value: _currentSliderValue,
38-
max: 100,
39-
divisions: 5,
40-
label: _currentSliderValue.round().toString(),
41-
onChanged: (double value) {
42-
setState(() {
43-
_currentSliderValue = value;
44-
});
45-
},
39+
body: Center(
40+
child: Column(
41+
mainAxisAlignment: MainAxisAlignment.center,
42+
spacing: 16,
43+
children: <Widget>[
44+
Slider(
45+
year2023: year2023,
46+
value: _currentSliderValue,
47+
max: 100,
48+
onChanged: (double value) {
49+
setState(() {
50+
_currentSliderValue = value;
51+
});
52+
},
53+
),
54+
Slider(
55+
year2023: year2023,
56+
value: _currentDiscreteSliderValue,
57+
max: 100,
58+
divisions: 5,
59+
label: _currentDiscreteSliderValue.round().toString(),
60+
onChanged: (double value) {
61+
setState(() {
62+
_currentDiscreteSliderValue = value;
63+
});
64+
},
65+
),
66+
SwitchListTile(
67+
value: year2023,
68+
title: year2023 ? const Text('Switch to latest M3 style') : const Text('Switch to year2023 M3 style'),
69+
onChanged: (bool value) {
70+
setState(() {
71+
year2023 = !year2023;
72+
});
73+
},
74+
),
75+
],
76+
),
4677
),
4778
);
4879
}

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

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,8 @@ class SliderApp extends StatelessWidget {
1313

1414
@override
1515
Widget build(BuildContext context) {
16-
return MaterialApp(
17-
theme: ThemeData(
18-
colorSchemeSeed: const Color(0xff6750a4),
19-
useMaterial3: true,
20-
),
21-
home: const SliderExample(),
16+
return const MaterialApp(
17+
home: SliderExample(),
2218
);
2319
}
2420
}
@@ -31,22 +27,36 @@ class SliderExample extends StatefulWidget {
3127
}
3228

3329
class _SliderExampleState extends State<SliderExample> {
34-
double _currentSliderValue = 20;
30+
double _currentSliderPrimaryValue = 0.2;
31+
double _currentSliderSecondaryValue = 0.5;
3532

3633
@override
3734
Widget build(BuildContext context) {
3835
return Scaffold(
3936
appBar: AppBar(title: const Text('Slider')),
40-
body: Slider(
41-
value: _currentSliderValue,
42-
max: 100,
43-
divisions: 5,
44-
label: _currentSliderValue.round().toString(),
45-
onChanged: (double value) {
46-
setState(() {
47-
_currentSliderValue = value;
48-
});
49-
},
37+
body: Column(
38+
mainAxisAlignment: MainAxisAlignment.center,
39+
children: <Widget>[
40+
Slider(
41+
value: _currentSliderPrimaryValue,
42+
secondaryTrackValue: _currentSliderSecondaryValue,
43+
label: _currentSliderPrimaryValue.round().toString(),
44+
onChanged: (double value) {
45+
setState(() {
46+
_currentSliderPrimaryValue = value;
47+
});
48+
},
49+
),
50+
Slider(
51+
value: _currentSliderSecondaryValue,
52+
label: _currentSliderSecondaryValue.round().toString(),
53+
onChanged: (double value) {
54+
setState(() {
55+
_currentSliderSecondaryValue = value;
56+
});
57+
},
58+
),
59+
],
5060
),
5161
);
5262
}

examples/api/lib/material/slider/slider.2.dart

Lines changed: 0 additions & 63 deletions
This file was deleted.

examples/api/test/material/slider/slider.0_test.dart

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,50 @@ import 'package:flutter_api_samples/material/slider/slider.0.dart' as example;
77
import 'package:flutter_test/flutter_test.dart';
88

99
void main() {
10-
testWidgets('Slider can change its value', (WidgetTester tester) async {
10+
testWidgets('Sliders can change their value', (WidgetTester tester) async {
1111
await tester.pumpWidget(
12-
const example.SliderApp(),
12+
const example.SliderExampleApp(),
1313
);
1414

15-
expect(find.byType(Slider), findsOneWidget);
15+
expect(find.byType(Slider), findsNWidgets(2));
1616

17-
final Finder sliderFinder = find.byType(Slider);
17+
Finder sliderFinder = find.byType(Slider).first;
18+
Slider slider = tester.widget<Slider>(sliderFinder);
19+
expect(slider.value, equals(20));
1820

19-
Slider slider = tester.widget(sliderFinder);
20-
expect(slider.value, 20);
21+
await tester.tapAt(tester.getCenter(sliderFinder));
22+
await tester.pump();
23+
24+
slider = tester.widget(sliderFinder);
25+
expect(slider.value, equals(50));
2126

22-
final Offset center = tester.getCenter(sliderFinder);
23-
await tester.tapAt(Offset(center.dx + 100, center.dy));
27+
sliderFinder = find.byType(Slider).last;
28+
slider = tester.widget(sliderFinder);
29+
expect(slider.value, equals(60));
30+
31+
await tester.tapAt(tester.getTopLeft(sliderFinder));
2432
await tester.pump();
2533

2634
slider = tester.widget(sliderFinder);
27-
expect(slider.value, 60.0);
35+
expect(slider.value, equals(0));
36+
});
37+
38+
testWidgets('Sliders year2023 flag can be toggled', (WidgetTester tester) async {
39+
await tester.pumpWidget(
40+
const example.SliderExampleApp(),
41+
);
42+
43+
Slider slider = tester.widget<Slider>(find.byType(Slider).first);
44+
expect(slider.year2023, true);
45+
Slider discreteSlider = tester.widget<Slider>(find.byType(Slider).last);
46+
expect(discreteSlider.year2023, true);
47+
48+
await tester.tap(find.byType(SwitchListTile));
49+
await tester.pumpAndSettle();
50+
51+
slider = tester.widget<Slider>(find.byType(Slider).first);
52+
expect(slider.year2023, false);
53+
discreteSlider = tester.widget<Slider>(find.byType(Slider).last);
54+
expect(discreteSlider.year2023, false);
2855
});
2956
}

examples/api/test/material/slider/slider.1_test.dart

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,29 @@ import 'package:flutter_api_samples/material/slider/slider.1.dart' as example;
77
import 'package:flutter_test/flutter_test.dart';
88

99
void main() {
10-
testWidgets('Slider can change its value', (WidgetTester tester) async {
10+
testWidgets('Slider shows secondary track', (WidgetTester tester) async {
1111
await tester.pumpWidget(
1212
const example.SliderApp(),
1313
);
1414

15-
expect(find.byType(Slider), findsOneWidget);
15+
expect(find.byType(Slider), findsNWidgets(2));
1616

17-
final Finder sliderFinder = find.byType(Slider);
17+
final Finder slider1Finder = find.byType(Slider).at(0);
18+
final Finder slider2Finder = find.byType(Slider).at(1);
1819

19-
Slider slider = tester.widget(sliderFinder);
20-
expect(slider.value, 20);
20+
Slider slider1 = tester.widget(slider1Finder);
21+
Slider slider2 = tester.widget(slider2Finder);
22+
expect(slider1.secondaryTrackValue, slider2.value);
2123

22-
final Offset center = tester.getCenter(sliderFinder);
23-
await tester.tapAt(Offset(center.dx + 100, center.dy));
24+
const double targetValue = 0.8;
25+
final Rect rect = tester.getRect(slider2Finder);
26+
final Offset target = Offset(rect.left + (rect.right - rect.left) * targetValue, rect.top + (rect.bottom - rect.top) / 2);
27+
await tester.tapAt(target);
2428
await tester.pump();
2529

26-
slider = tester.widget(sliderFinder);
27-
expect(slider.value, 60.0);
30+
slider1 = tester.widget(slider1Finder);
31+
slider2 = tester.widget(slider2Finder);
32+
expect(slider1.secondaryTrackValue, closeTo(targetValue, 0.05));
33+
expect(slider1.secondaryTrackValue, slider2.value);
2834
});
2935
}

examples/api/test/material/slider/slider.2_test.dart

Lines changed: 0 additions & 35 deletions
This file was deleted.

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

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,27 +78,18 @@ enum SliderInteraction {
7878
/// {@youtube 560 315 https://www.youtube.com/watch?v=ufb4gIPDmEs}
7979
///
8080
/// {@tool dartpad}
81-
/// ![A legacy slider widget, consisting of 5 divisions and showing the default value
82-
/// indicator.](https://flutter.github.io/assets-for-api-docs/assets/material/slider.png)
83-
///
84-
/// The Sliders value is part of the Stateful widget subclass to change the value
85-
/// setState was called.
81+
/// This example showcases non-discrete and discrete [Slider]s.
82+
/// The [Slider]s will show the updated ![Material 3 Design appearance](https://m3.material.io/components/sliders/overview)
83+
/// when setting the [Slider.year2023] flag to false.
8684
///
8785
/// ** See code in examples/api/lib/material/slider/slider.0.dart **
8886
/// {@end-tool}
8987
///
9088
/// {@tool dartpad}
91-
/// This sample shows the creation of a [Slider] using [ThemeData.useMaterial3] flag,
92-
/// as described in: https://m3.material.io/components/sliders/overview.
93-
///
94-
/// ** See code in examples/api/lib/material/slider/slider.1.dart **
95-
/// {@end-tool}
96-
///
97-
/// {@tool dartpad}
9889
/// This example shows a [Slider] widget using the [Slider.secondaryTrackValue]
9990
/// to show a secondary track in the slider.
10091
///
101-
/// ** See code in examples/api/lib/material/slider/slider.2.dart **
92+
/// ** See code in examples/api/lib/material/slider/slider.1.dart **
10293
/// {@end-tool}
10394
///
10495
/// A slider can be used to select from either a continuous or a discrete set of

0 commit comments

Comments
 (0)