Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Material 3 Slider example #115638

Merged
merged 3 commits into from
Dec 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 22 additions & 25 deletions examples/api/lib/material/slider/slider.0.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,44 @@

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());
void main() => runApp(const SliderApp());

class MyApp extends StatelessWidget {
const MyApp({super.key});

static const String _title = 'Flutter Code Sample';
class SliderApp extends StatelessWidget {
const SliderApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatefulWidget(),
),
return const MaterialApp(
home: SliderExample(),
);
}
}

class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
class SliderExample extends StatefulWidget {
const SliderExample({super.key});

@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
State<SliderExample> createState() => _SliderExampleState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
class _SliderExampleState extends State<SliderExample> {
double _currentSliderValue = 20;

@override
Widget build(BuildContext context) {
return Slider(
value: _currentSliderValue,
max: 100,
divisions: 5,
label: _currentSliderValue.round().toString(),
onChanged: (double value) {
setState(() {
_currentSliderValue = value;
});
},
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;
});
},
),
);
}
}
63 changes: 25 additions & 38 deletions examples/api/lib/material/slider/slider.1.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,48 @@

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());
void main() => runApp(const SliderApp());

class MyApp extends StatelessWidget {
const MyApp({super.key});

static const String _title = 'Flutter Code Sample';
class SliderApp extends StatelessWidget {
const SliderApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatefulWidget(),
theme: ThemeData(
colorSchemeSeed: const Color(0xff6750a4),
useMaterial3: true,
),
home: const SliderExample(),
);
}
}

class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
class SliderExample extends StatefulWidget {
const SliderExample({super.key});

@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
State<SliderExample> createState() => _SliderExampleState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
double _currentSliderPrimaryValue = 0.2;
double _currentSliderSecondaryValue = 0.5;
class _SliderExampleState extends State<SliderExample> {
double _currentSliderValue = 20;

@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
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;
});
},
),
],
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;
});
},
),
);
}
}
63 changes: 63 additions & 0 deletions examples/api/lib/material/slider/slider.2.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// 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 [Slider].

import 'package:flutter/material.dart';

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<SliderExample> createState() => _SliderExampleState();
}

class _SliderExampleState extends State<SliderExample> {
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: <Widget>[
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;
});
},
),
],
),
);
}
}
29 changes: 29 additions & 0 deletions examples/api/test/material/slider/slider.0_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// 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.0.dart' as example;
import 'package:flutter_test/flutter_test.dart';

void main() {
testWidgets('Slider can change its value', (WidgetTester tester) async {
await tester.pumpWidget(
const example.SliderApp(),
);

expect(find.byType(Slider), findsOneWidget);

final Finder sliderFinder = find.byType(Slider);

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.pump();

slider = tester.widget(sliderFinder);
expect(slider.value, 60.0);
});
}
26 changes: 10 additions & 16 deletions examples/api/test/material/slider/slider.1_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,23 @@ import 'package:flutter_api_samples/material/slider/slider.1.dart' as example;
import 'package:flutter_test/flutter_test.dart';

void main() {
testWidgets('Slider shows secondary track', (WidgetTester tester) async {
testWidgets('Slider can change its value', (WidgetTester tester) async {
await tester.pumpWidget(
const example.MyApp(),
const example.SliderApp(),
);

expect(find.byType(Slider), findsNWidgets(2));
expect(find.byType(Slider), findsOneWidget);

final Finder slider1Finder = find.byType(Slider).at(0);
final Finder slider2Finder = find.byType(Slider).at(1);
final Finder sliderFinder = find.byType(Slider);

Slider slider1 = tester.widget(slider1Finder);
Slider slider2 = tester.widget(slider2Finder);
expect(slider1.secondaryTrackValue, slider2.value);
Slider slider = tester.widget(sliderFinder);
expect(slider.value, 20);

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);
final Offset center = tester.getCenter(sliderFinder);
await tester.tapAt(Offset(center.dx + 100, center.dy));
await tester.pump();

slider1 = tester.widget(slider1Finder);
slider2 = tester.widget(slider2Finder);
expect(slider1.secondaryTrackValue, closeTo(targetValue, 0.05));
expect(slider1.secondaryTrackValue, slider2.value);
slider = tester.widget(sliderFinder);
expect(slider.value, 60.0);
});
}
35 changes: 35 additions & 0 deletions examples/api/test/material/slider/slider.2_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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);
});
}
11 changes: 9 additions & 2 deletions packages/flutter/lib/src/material/slider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ enum _SliderType { material, adaptive }
/// {@youtube 560 315 https://www.youtube.com/watch?v=ufb4gIPDmEs}
///
/// {@tool dartpad}
/// ![A slider widget, consisting of 5 divisions and showing the default value
/// ![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
Expand All @@ -51,10 +51,17 @@ enum _SliderType { material, adaptive }
/// {@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 **
TahaTesser marked this conversation as resolved.
Show resolved Hide resolved
/// {@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.1.dart **
/// ** See code in examples/api/lib/material/slider/slider.2.dart **
/// {@end-tool}
///
/// A slider can be used to select from either a continuous or a discrete set of
Expand Down