Skip to content

Commit cae4be7

Browse files
feat: add cupertino slider field
1 parent 381ed64 commit cae4be7

7 files changed

+414
-6
lines changed

example/lib/main.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,17 @@ class _MyHomePageState extends State<MyHomePage> {
7474
decoration: const InputDecoration(
7575
prefix: Text('Enable/Disabled'),
7676
),
77-
)
77+
),
78+
FormBuilderCupertinoSlider(
79+
name: 'slider',
80+
initialValue: 10,
81+
autovalidateMode: AutovalidateMode.onUserInteraction,
82+
min: 1,
83+
max: 100,
84+
validator: (value) => value != null && value < 50 && value > 5
85+
? null
86+
: 'Required value between 5 and 50',
87+
),
7888
],
7989
),
8090
), // This trailing comma makes auto-formatting nicer for build methods.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
library form_builder_cupertino_fields;
22

33
export 'src/fields/form_builder_cupertino_segmented_control.dart';
4+
export 'src/fields/form_builder_cupertino_slider.dart';
45
export 'src/fields/form_builder_cupertino_sliding_segmented_control.dart';
56
export 'src/fields/form_builder_cupertino_switch.dart';
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
import 'package:flutter/cupertino.dart';
2+
3+
import 'package:flutter_form_builder/flutter_form_builder.dart';
4+
import 'package:intl/intl.dart';
5+
6+
import '../widgets/cupertino_input_decoration.dart';
7+
8+
/// Field for selection of a numerical value on a slider
9+
class FormBuilderCupertinoSlider extends FormBuilderField<double> {
10+
/// Called when the user starts selecting a new value for the slider.
11+
///
12+
/// This callback shouldn't be used to update the slider [value] (use
13+
/// [onChanged] for that), but rather to be notified when the user has started
14+
/// selecting a new value by starting a drag or with a tap.
15+
///
16+
/// The value passed will be the last [value] that the slider had before the
17+
/// change began.
18+
///
19+
/// See also:
20+
///
21+
/// * [onChangeEnd] for a callback that is called when the value change is
22+
/// complete.
23+
final ValueChanged<double>? onChangeStart;
24+
25+
/// Called when the user is done selecting a new value for the slider.
26+
///
27+
/// This callback shouldn't be used to update the slider [value] (use
28+
/// [onChanged] for that), but rather to know when the user has completed
29+
/// selecting a new [value] by ending a drag or a click.
30+
/// See also:
31+
///
32+
/// * [onChangeStart] for a callback that is called when a value change
33+
/// begins.
34+
final ValueChanged<double>? onChangeEnd;
35+
36+
/// The minimum value the user can select.
37+
///
38+
/// Defaults to 0.0. Must be less than or equal to [max].
39+
///
40+
/// If the [max] is equal to the [min], then the slider is disabled.
41+
final double min;
42+
43+
/// The maximum value the user can select.
44+
///
45+
/// Defaults to 1.0. Must be greater than or equal to [min].
46+
///
47+
/// If the [max] is equal to the [min], then the slider is disabled.
48+
final double max;
49+
50+
/// The number of discrete divisions.
51+
///
52+
/// If null, the slider is continuous.
53+
final int? divisions;
54+
55+
/// The color to use for the portion of the slider that has been selected.
56+
///
57+
/// Defaults to the [CupertinoTheme]'s primary color if null.
58+
final Color? activeColor;
59+
60+
/// The color to use for the thumb of the slider.
61+
///
62+
/// Thumb color must not be null.
63+
///
64+
/// Defaults to [CupertinoColors.white].
65+
final Color thumbColor;
66+
67+
/// An alternative to displaying the text value of the slider.
68+
///
69+
/// Defaults to null.
70+
///
71+
/// When used [minValueWidget] will override the value for the minimum widget.
72+
final Widget Function(String min)? minValueWidget;
73+
74+
/// An alternative to displaying the text value of the slider.
75+
///
76+
/// Defaults to null.
77+
///
78+
/// When used [valueWidget] will override the value for the selected value widget.
79+
final Widget Function(String value)? valueWidget;
80+
81+
/// An alternative to displaying the text value of the slider.
82+
///
83+
/// Defaults to null.
84+
///
85+
/// When used [maxValueWidget] will override the value for the maximum widget.
86+
final Widget Function(String max)? maxValueWidget;
87+
88+
/// Provides the ability to format a number in a locale-specific way.
89+
///
90+
/// The format is specified as a pattern using a subset of the ICU formatting
91+
/// patterns.
92+
///
93+
/// - `0` A single digit
94+
/// - `#` A single digit, omitted if the value is zero
95+
/// - `.` Decimal separator
96+
/// - `-` Minus sign
97+
/// - `,` Grouping separator
98+
/// - `E` Separates mantissa and expontent
99+
/// - `+` - Before an exponent, to say it should be prefixed with a plus sign.
100+
/// - `%` - In prefix or suffix, multiply by 100 and show as percentage
101+
/// - `‰ (\u2030)` In prefix or suffix, multiply by 1000 and show as per mille
102+
/// - `¤ (\u00A4)` Currency sign, replaced by currency name
103+
/// - `'` Used to quote special characters
104+
/// - `;` Used to separate the positive and negative patterns (if both present)
105+
///
106+
/// For example,
107+
///
108+
/// var f = NumberFormat("###.0#", "en_US");
109+
/// print(f.format(12.345));
110+
/// ==> 12.34
111+
///
112+
/// If the locale is not specified, it will default to the current locale. If
113+
/// the format is not specified it will print in a basic format with at least
114+
/// one integer digit and three fraction digits.
115+
///
116+
/// There are also standard patterns available via the special constructors.
117+
/// e.g.
118+
///
119+
/// var percent = NumberFormat.percentPattern("ar"); var
120+
/// eurosInUSFormat = NumberFormat.currency(locale: "en_US",
121+
/// symbol: "€");
122+
///
123+
/// There are several such constructors available, though some of them are
124+
/// limited. For example, at the moment, scientificPattern prints only as
125+
/// equivalent to "#E0" and does not take into account significant digits.
126+
final NumberFormat? numberFormat;
127+
128+
final DisplayValues displayValues;
129+
130+
/// Creates field for selection of a numerical value on a slider
131+
FormBuilderCupertinoSlider({
132+
super.key,
133+
required super.name,
134+
super.validator,
135+
required double super.initialValue,
136+
super.decoration,
137+
super.onChanged,
138+
super.valueTransformer,
139+
super.enabled,
140+
super.onSaved,
141+
super.autovalidateMode,
142+
super.onReset,
143+
super.focusNode,
144+
super.restorationId,
145+
required this.min,
146+
required this.max,
147+
this.divisions,
148+
this.activeColor,
149+
this.thumbColor = CupertinoColors.white,
150+
this.onChangeStart,
151+
this.onChangeEnd,
152+
this.numberFormat,
153+
this.displayValues = DisplayValues.all,
154+
this.maxValueWidget,
155+
this.minValueWidget,
156+
this.valueWidget,
157+
}) : super(
158+
builder: (FormFieldState<double?> field) {
159+
final state = field as _FormBuilderCupertinoSliderState;
160+
final effectiveNumberFormat =
161+
numberFormat ?? NumberFormat.compact();
162+
163+
return CupertinoInputDecoration(
164+
fieldState: state,
165+
child: Column(
166+
mainAxisSize: MainAxisSize.min,
167+
crossAxisAlignment: CrossAxisAlignment.end,
168+
children: [
169+
SizedBox(
170+
width: double.infinity,
171+
child: CupertinoSlider(
172+
value: field.value!,
173+
min: min,
174+
max: max,
175+
divisions: divisions,
176+
activeColor: activeColor,
177+
onChangeEnd: onChangeEnd,
178+
onChangeStart: onChangeStart,
179+
onChanged: state.enabled
180+
? (value) {
181+
field.didChange(value);
182+
}
183+
: null,
184+
thumbColor: thumbColor,
185+
),
186+
),
187+
Row(
188+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
189+
children: <Widget>[
190+
if (displayValues != DisplayValues.none &&
191+
displayValues != DisplayValues.current)
192+
minValueWidget
193+
?.call(effectiveNumberFormat.format(min)) ??
194+
Text(effectiveNumberFormat.format(min)),
195+
if (displayValues != DisplayValues.none &&
196+
displayValues != DisplayValues.minMax)
197+
valueWidget?.call(
198+
effectiveNumberFormat.format(field.value)) ??
199+
Text(effectiveNumberFormat.format(field.value)),
200+
if (displayValues != DisplayValues.none &&
201+
displayValues != DisplayValues.current)
202+
maxValueWidget
203+
?.call(effectiveNumberFormat.format(max)) ??
204+
Text(effectiveNumberFormat.format(max)),
205+
],
206+
),
207+
],
208+
),
209+
);
210+
},
211+
);
212+
213+
@override
214+
FormBuilderFieldState<FormBuilderCupertinoSlider, double> createState() =>
215+
_FormBuilderCupertinoSliderState();
216+
}
217+
218+
class _FormBuilderCupertinoSliderState
219+
extends FormBuilderFieldState<FormBuilderCupertinoSlider, double> {}

lib/src/fields/form_builder_cupertino_switch.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import 'package:flutter/cupertino.dart';
22
import 'package:flutter/gestures.dart';
3-
import 'package:flutter/material.dart';
43

54
import 'package:flutter_form_builder/flutter_form_builder.dart';
65

@@ -74,7 +73,7 @@ class FormBuilderCupertinoSwitch extends FormBuilderField<bool> {
7473
this.thumbColor,
7574
}) : super(
7675
builder: (FormFieldState<bool?> field) {
77-
final state = field as _FormBuilderSwitchState;
76+
final state = field as _FormBuilderCupertinoSwitchState;
7877

7978
final fieldWidget = CupertinoSwitch(
8079
value: state.value ?? false,
@@ -100,8 +99,8 @@ class FormBuilderCupertinoSwitch extends FormBuilderField<bool> {
10099

101100
@override
102101
FormBuilderFieldState<FormBuilderCupertinoSwitch, bool> createState() =>
103-
_FormBuilderSwitchState();
102+
_FormBuilderCupertinoSwitchState();
104103
}
105104

106-
class _FormBuilderSwitchState
105+
class _FormBuilderCupertinoSwitchState
107106
extends FormBuilderFieldState<FormBuilderCupertinoSwitch, bool> {}

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ dependencies:
1515
flutter:
1616
sdk: flutter
1717
flutter_form_builder: ^8.0.0
18+
intl: ^0.17.0
1819

1920
dev_dependencies:
2021
flutter_test:

0 commit comments

Comments
 (0)