diff --git a/examples/api/lib/material/slider/slider.0.dart b/examples/api/lib/material/slider/slider.0.dart index f73efb81c46..2c508b8c6af 100644 --- a/examples/api/lib/material/slider/slider.0.dart +++ b/examples/api/lib/material/slider/slider.0.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; /// Flutter code sample for [Slider]. +/// set to false. -void main() => runApp(const SliderApp()); +void main() => runApp(const SliderExampleApp()); -class SliderApp extends StatelessWidget { - const SliderApp({super.key}); +class SliderExampleApp extends StatelessWidget { + const SliderExampleApp({super.key}); @override Widget build(BuildContext context) { @@ -28,21 +29,51 @@ class SliderExample extends StatefulWidget { class _SliderExampleState extends State { double _currentSliderValue = 20; + double _currentDiscreteSliderValue = 60; + bool year2023 = true; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Slider')), - body: Slider( - value: _currentSliderValue, - max: 100, - divisions: 5, - label: _currentSliderValue.round().toString(), - onChanged: (double value) { - setState(() { - _currentSliderValue = value; - }); - }, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16, + children: [ + Slider( + year2023: year2023, + value: _currentSliderValue, + max: 100, + onChanged: (double value) { + setState(() { + _currentSliderValue = value; + }); + }, + ), + Slider( + year2023: year2023, + value: _currentDiscreteSliderValue, + max: 100, + divisions: 5, + label: _currentDiscreteSliderValue.round().toString(), + onChanged: (double value) { + setState(() { + _currentDiscreteSliderValue = value; + }); + }, + ), + SwitchListTile( + value: year2023, + title: year2023 ? const Text('Switch to latest M3 style') : const Text('Switch to year2023 M3 style'), + onChanged: (bool value) { + setState(() { + year2023 = !year2023; + }); + }, + ), + ], + ), ), ); } diff --git a/examples/api/lib/material/slider/slider.1.dart b/examples/api/lib/material/slider/slider.1.dart index f5c791fa111..b5716712cc5 100644 --- a/examples/api/lib/material/slider/slider.1.dart +++ b/examples/api/lib/material/slider/slider.1.dart @@ -13,12 +13,8 @@ class SliderApp extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( - theme: ThemeData( - colorSchemeSeed: const Color(0xff6750a4), - useMaterial3: true, - ), - home: const SliderExample(), + return const MaterialApp( + home: SliderExample(), ); } } @@ -31,22 +27,36 @@ class SliderExample extends StatefulWidget { } class _SliderExampleState extends State { - double _currentSliderValue = 20; + double _currentSliderPrimaryValue = 0.2; + double _currentSliderSecondaryValue = 0.5; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Slider')), - body: Slider( - value: _currentSliderValue, - max: 100, - divisions: 5, - label: _currentSliderValue.round().toString(), - onChanged: (double value) { - setState(() { - _currentSliderValue = value; - }); - }, + body: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Slider( + value: _currentSliderPrimaryValue, + secondaryTrackValue: _currentSliderSecondaryValue, + label: _currentSliderPrimaryValue.round().toString(), + onChanged: (double value) { + setState(() { + _currentSliderPrimaryValue = value; + }); + }, + ), + Slider( + value: _currentSliderSecondaryValue, + label: _currentSliderSecondaryValue.round().toString(), + onChanged: (double value) { + setState(() { + _currentSliderSecondaryValue = value; + }); + }, + ), + ], ), ); } diff --git a/examples/api/lib/material/slider/slider.2.dart b/examples/api/lib/material/slider/slider.2.dart deleted file mode 100644 index b5716712cc5..00000000000 --- a/examples/api/lib/material/slider/slider.2.dart +++ /dev/null @@ -1,63 +0,0 @@ -// 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'; - -/// Flutter code sample for [Slider]. - -void main() => runApp(const SliderApp()); - -class SliderApp extends StatelessWidget { - const SliderApp({super.key}); - - @override - Widget build(BuildContext context) { - return const MaterialApp( - home: SliderExample(), - ); - } -} - -class SliderExample extends StatefulWidget { - const SliderExample({super.key}); - - @override - State createState() => _SliderExampleState(); -} - -class _SliderExampleState extends State { - double _currentSliderPrimaryValue = 0.2; - double _currentSliderSecondaryValue = 0.5; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: const Text('Slider')), - body: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Slider( - value: _currentSliderPrimaryValue, - secondaryTrackValue: _currentSliderSecondaryValue, - label: _currentSliderPrimaryValue.round().toString(), - onChanged: (double value) { - setState(() { - _currentSliderPrimaryValue = value; - }); - }, - ), - Slider( - value: _currentSliderSecondaryValue, - label: _currentSliderSecondaryValue.round().toString(), - onChanged: (double value) { - setState(() { - _currentSliderSecondaryValue = value; - }); - }, - ), - ], - ), - ); - } -} diff --git a/examples/api/test/material/slider/slider.0_test.dart b/examples/api/test/material/slider/slider.0_test.dart index 8ab403e3eb0..9db8e95f59d 100644 --- a/examples/api/test/material/slider/slider.0_test.dart +++ b/examples/api/test/material/slider/slider.0_test.dart @@ -7,23 +7,50 @@ import 'package:flutter_api_samples/material/slider/slider.0.dart' as example; import 'package:flutter_test/flutter_test.dart'; void main() { - testWidgets('Slider can change its value', (WidgetTester tester) async { + testWidgets('Sliders can change their value', (WidgetTester tester) async { await tester.pumpWidget( - const example.SliderApp(), + const example.SliderExampleApp(), ); - expect(find.byType(Slider), findsOneWidget); + expect(find.byType(Slider), findsNWidgets(2)); - final Finder sliderFinder = find.byType(Slider); + Finder sliderFinder = find.byType(Slider).first; + Slider slider = tester.widget(sliderFinder); + expect(slider.value, equals(20)); - Slider slider = tester.widget(sliderFinder); - expect(slider.value, 20); - - final Offset center = tester.getCenter(sliderFinder); - await tester.tapAt(Offset(center.dx + 100, center.dy)); + await tester.tapAt(tester.getCenter(sliderFinder)); await tester.pump(); slider = tester.widget(sliderFinder); - expect(slider.value, 60.0); + expect(slider.value, equals(50)); + + sliderFinder = find.byType(Slider).last; + slider = tester.widget(sliderFinder); + expect(slider.value, equals(60)); + + await tester.tapAt(tester.getTopLeft(sliderFinder)); + await tester.pump(); + + slider = tester.widget(sliderFinder); + expect(slider.value, equals(0)); + }); + + testWidgets('Sliders year2023 flag can be toggled', (WidgetTester tester) async { + await tester.pumpWidget( + const example.SliderExampleApp(), + ); + + Slider slider = tester.widget(find.byType(Slider).first); + expect(slider.year2023, true); + Slider discreteSlider = tester.widget(find.byType(Slider).last); + expect(discreteSlider.year2023, true); + + await tester.tap(find.byType(SwitchListTile)); + await tester.pumpAndSettle(); + + slider = tester.widget(find.byType(Slider).first); + expect(slider.year2023, false); + discreteSlider = tester.widget(find.byType(Slider).last); + expect(discreteSlider.year2023, false); }); } diff --git a/examples/api/test/material/slider/slider.1_test.dart b/examples/api/test/material/slider/slider.1_test.dart index 3cdfc5cdb7c..9096c90b008 100644 --- a/examples/api/test/material/slider/slider.1_test.dart +++ b/examples/api/test/material/slider/slider.1_test.dart @@ -7,23 +7,29 @@ import 'package:flutter_api_samples/material/slider/slider.1.dart' as example; import 'package:flutter_test/flutter_test.dart'; void main() { - testWidgets('Slider can change its value', (WidgetTester tester) async { + testWidgets('Slider shows secondary track', (WidgetTester tester) async { await tester.pumpWidget( const example.SliderApp(), ); - expect(find.byType(Slider), findsOneWidget); + expect(find.byType(Slider), findsNWidgets(2)); - final Finder sliderFinder = find.byType(Slider); + final Finder slider1Finder = find.byType(Slider).at(0); + final Finder slider2Finder = find.byType(Slider).at(1); - Slider slider = tester.widget(sliderFinder); - expect(slider.value, 20); + Slider slider1 = tester.widget(slider1Finder); + Slider slider2 = tester.widget(slider2Finder); + expect(slider1.secondaryTrackValue, slider2.value); - final Offset center = tester.getCenter(sliderFinder); - await tester.tapAt(Offset(center.dx + 100, center.dy)); + const double targetValue = 0.8; + final Rect rect = tester.getRect(slider2Finder); + final Offset target = Offset(rect.left + (rect.right - rect.left) * targetValue, rect.top + (rect.bottom - rect.top) / 2); + await tester.tapAt(target); await tester.pump(); - slider = tester.widget(sliderFinder); - expect(slider.value, 60.0); + slider1 = tester.widget(slider1Finder); + slider2 = tester.widget(slider2Finder); + expect(slider1.secondaryTrackValue, closeTo(targetValue, 0.05)); + expect(slider1.secondaryTrackValue, slider2.value); }); } diff --git a/examples/api/test/material/slider/slider.2_test.dart b/examples/api/test/material/slider/slider.2_test.dart deleted file mode 100644 index 1ec99374587..00000000000 --- a/examples/api/test/material/slider/slider.2_test.dart +++ /dev/null @@ -1,35 +0,0 @@ -// 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/slider/slider.2.dart' as example; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - testWidgets('Slider shows secondary track', (WidgetTester tester) async { - await tester.pumpWidget( - const example.SliderApp(), - ); - - expect(find.byType(Slider), findsNWidgets(2)); - - final Finder slider1Finder = find.byType(Slider).at(0); - final Finder slider2Finder = find.byType(Slider).at(1); - - Slider slider1 = tester.widget(slider1Finder); - Slider slider2 = tester.widget(slider2Finder); - expect(slider1.secondaryTrackValue, slider2.value); - - const double targetValue = 0.8; - final Rect rect = tester.getRect(slider2Finder); - final Offset target = Offset(rect.left + (rect.right - rect.left) * targetValue, rect.top + (rect.bottom - rect.top) / 2); - await tester.tapAt(target); - await tester.pump(); - - slider1 = tester.widget(slider1Finder); - slider2 = tester.widget(slider2Finder); - expect(slider1.secondaryTrackValue, closeTo(targetValue, 0.05)); - expect(slider1.secondaryTrackValue, slider2.value); - }); -} diff --git a/packages/flutter/lib/src/material/slider.dart b/packages/flutter/lib/src/material/slider.dart index 48c93151357..5078cb19dd7 100644 --- a/packages/flutter/lib/src/material/slider.dart +++ b/packages/flutter/lib/src/material/slider.dart @@ -78,27 +78,18 @@ enum SliderInteraction { /// {@youtube 560 315 https://www.youtube.com/watch?v=ufb4gIPDmEs} /// /// {@tool dartpad} -/// ![A legacy slider widget, consisting of 5 divisions and showing the default value -/// indicator.](https://flutter.github.io/assets-for-api-docs/assets/material/slider.png) -/// -/// The Sliders value is part of the Stateful widget subclass to change the value -/// setState was called. +/// This example showcases non-discrete and discrete [Slider]s. +/// The [Slider]s will show the updated ![Material 3 Design appearance](https://m3.material.io/components/sliders/overview) +/// when setting the [Slider.year2023] flag to false. /// /// ** See code in examples/api/lib/material/slider/slider.0.dart ** /// {@end-tool} /// /// {@tool dartpad} -/// This sample shows the creation of a [Slider] using [ThemeData.useMaterial3] flag, -/// as described in: https://m3.material.io/components/sliders/overview. -/// -/// ** See code in examples/api/lib/material/slider/slider.1.dart ** -/// {@end-tool} -/// -/// {@tool dartpad} /// This example shows a [Slider] widget using the [Slider.secondaryTrackValue] /// to show a secondary track in the slider. /// -/// ** See code in examples/api/lib/material/slider/slider.2.dart ** +/// ** See code in examples/api/lib/material/slider/slider.1.dart ** /// {@end-tool} /// /// A slider can be used to select from either a continuous or a discrete set of