Skip to content

Commit

Permalink
Merge ea510b0 into 8c0d5db
Browse files Browse the repository at this point in the history
  • Loading branch information
moniaS committed Aug 2, 2019
2 parents 8c0d5db + ea510b0 commit f97281e
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 64 deletions.
39 changes: 38 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,27 @@ class _MyHomePageState extends State<MyHomePage> {
int _currentIntValue = 10;
int _currentHorizontalIntValue = 10;
int _currentInfIntValue = 10;
int _currentInfIntValueDecorated = 10;
double _currentDoubleValue = 3.0;
NumberPicker integerNumberPicker;
NumberPicker horizontalNumberPicker;
NumberPicker integerInfiniteNumberPicker;
NumberPicker integerInfiniteDecoratedNumberPicker;
NumberPicker decimalNumberPicker;

Decoration _decoration = new BoxDecoration(
border: new Border(
top: new BorderSide(
style: BorderStyle.solid,
color: Colors.black26,
),
bottom: new BorderSide(
style: BorderStyle.solid,
color: Colors.black26,
),
),
);

@override
Widget build(BuildContext context) {
_initializeNumberPickers();
Expand Down Expand Up @@ -88,11 +103,22 @@ class _MyHomePageState extends State<MyHomePage> {
),
Column(
children: <Widget>[
SizedBox(height: 16),
Text('Default', style: Theme.of(context).textTheme.title),
integerInfiniteNumberPicker,
new RaisedButton(
onPressed: () => _showInfIntDialog(),
child: new Text("Current int value: $_currentInfIntValue"),
),
Divider(color: Colors.grey, height: 32),
Text('Decorated', style: Theme.of(context).textTheme.title),
integerInfiniteDecoratedNumberPicker,
Text(
"Current int value: $_currentInfIntValueDecorated",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
],
)
],
Expand Down Expand Up @@ -125,6 +151,17 @@ class _MyHomePageState extends State<MyHomePage> {
infiniteLoop: true,
onChanged: (value) => setState(() => _currentInfIntValue = value),
);
integerInfiniteDecoratedNumberPicker = new NumberPicker.integer(
initialValue: _currentInfIntValueDecorated,
minValue: 0,
maxValue: 99,
step: 10,
infiniteLoop: true,
highlightSelectedValue: false,
decoration: _decoration,
onChanged: (value) =>
setState(() => _currentInfIntValueDecorated = value),
);
decimalNumberPicker = new NumberPicker.decimal(
initialValue: _currentDoubleValue,
minValue: 1,
Expand Down Expand Up @@ -188,7 +225,7 @@ class _MyHomePageState extends State<MyHomePage> {
).then((num value) {
if (value != null) {
setState(() => _currentDoubleValue = value);
decimalNumberPicker.animateInt(value);
decimalNumberPicker.animateDecimalAndInteger(value);
}
});
}
Expand Down
207 changes: 145 additions & 62 deletions lib/numberpicker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class NumberPicker extends StatelessWidget {
this.listViewHeight = kDefaultListViewCrossAxisSize,
this.step = 1,
this.zeroPad = false,
this.highlightSelectedValue = true,
this.decoration,
}) : assert(initialValue != null),
assert(minValue != null),
assert(maxValue != null),
Expand Down Expand Up @@ -60,6 +62,8 @@ class NumberPicker extends StatelessWidget {
this.scrollDirection = Axis.vertical,
this.infiniteLoop = false,
this.zeroPad = false,
this.highlightSelectedValue = true,
this.decoration,
}) : assert(initialValue != null),
assert(minValue != null),
assert(maxValue != null),
Expand Down Expand Up @@ -94,6 +98,8 @@ class NumberPicker extends StatelessWidget {
this.decimalPlaces = 1,
this.itemExtent = kDefaultItemExtent,
this.listViewWidth = kDefaultListViewCrossAxisSize,
this.highlightSelectedValue = true,
this.decoration,
}) : assert(initialValue != null),
assert(minValue != null),
assert(maxValue != null),
Expand Down Expand Up @@ -155,6 +161,12 @@ class NumberPicker extends StatelessWidget {
///Currently selected decimal value
final int selectedDecimalValue;

///If currently selected value should be highlighted
final bool highlightSelectedValue;

///Decoration to apply to central box where the selected value is placed
final Decoration decoration;

///Step between elements. Only for integer datePicker
///Examples:
/// if step is 100 the following elements may be 100, 200, 300...
Expand Down Expand Up @@ -234,30 +246,41 @@ class NumberPicker extends StatelessWidget {
child: new Container(
height: listViewHeight,
width: listViewWidth,
child: new ListView.builder(
scrollDirection: scrollDirection,
controller: intScrollController,
itemExtent: itemExtent,
itemCount: listItemCount,
cacheExtent: _calculateCacheExtent(listItemCount),
itemBuilder: (BuildContext context, int index) {
final int value = _intValueFromIndex(index);

//define special style for selected (middle) element
final TextStyle itemStyle =
value == selectedIntValue ? selectedStyle : defaultStyle;

bool isExtra = index == 0 || index == listItemCount - 1;

return isExtra
? new Container() //empty first and last element
: new Center(
child: new Text(
getDisplayedValue(value),
style: itemStyle,
),
);
},
child: Stack(
children: <Widget>[
new ListView.builder(
scrollDirection: scrollDirection,
controller: intScrollController,
itemExtent: itemExtent,
itemCount: listItemCount,
cacheExtent: _calculateCacheExtent(listItemCount),
itemBuilder: (BuildContext context, int index) {
final int value = _intValueFromIndex(index);

//define special style for selected (middle) element
final TextStyle itemStyle =
value == selectedIntValue && highlightSelectedValue
? selectedStyle
: defaultStyle;

bool isExtra = index == 0 || index == listItemCount - 1;

return isExtra
? new Container() //empty first and last element
: new Center(
child: new Text(
getDisplayedValue(value),
style: itemStyle,
),
);
},
),
_NumberPickerSelectedItemDecoration(
axis: scrollDirection,
itemExtent: itemExtent,
decoration: decoration,
),
],
),
),
onNotification: _onIntegerNotification,
Expand All @@ -276,27 +299,38 @@ class NumberPicker extends StatelessWidget {
child: new Container(
height: listViewHeight,
width: listViewWidth,
child: new ListView.builder(
controller: decimalScrollController,
itemExtent: itemExtent,
itemCount: decimalItemCount,
itemBuilder: (BuildContext context, int index) {
final int value = index - 1;

//define special style for selected (middle) element
final TextStyle itemStyle =
value == selectedDecimalValue ? selectedStyle : defaultStyle;

bool isExtra = index == 0 || index == decimalItemCount - 1;

return isExtra
? new Container() //empty first and last element
: new Center(
child: new Text(
value.toString().padLeft(decimalPlaces, '0'),
style: itemStyle),
);
},
child: Stack(
children: <Widget>[
new ListView.builder(
controller: decimalScrollController,
itemExtent: itemExtent,
itemCount: decimalItemCount,
itemBuilder: (BuildContext context, int index) {
final int value = index - 1;

//define special style for selected (middle) element
final TextStyle itemStyle =
value == selectedDecimalValue && highlightSelectedValue
? selectedStyle
: defaultStyle;

bool isExtra = index == 0 || index == decimalItemCount - 1;

return isExtra
? new Container() //empty first and last element
: new Center(
child: new Text(
value.toString().padLeft(decimalPlaces, '0'),
style: itemStyle),
);
},
),
_NumberPickerSelectedItemDecoration(
axis: scrollDirection,
itemExtent: itemExtent,
decoration: decoration,
),
],
),
),
onNotification: _onDecimalNotification,
Expand All @@ -312,23 +346,34 @@ class NumberPicker extends StatelessWidget {
child: new Container(
height: listViewHeight,
width: listViewWidth,
child: new InfiniteListView.builder(
controller: intScrollController,
itemExtent: itemExtent,
itemBuilder: (BuildContext context, int index) {
final int value = _intValueFromIndex(index);

//define special style for selected (middle) element
final TextStyle itemStyle =
value == selectedIntValue ? selectedStyle : defaultStyle;

return new Center(
child: new Text(
getDisplayedValue(value),
style: itemStyle,
),
);
},
child: Stack(
children: <Widget>[
InfiniteListView.builder(
controller: intScrollController,
itemExtent: itemExtent,
itemBuilder: (BuildContext context, int index) {
final int value = _intValueFromIndex(index);

//define special style for selected (middle) element
final TextStyle itemStyle =
value == selectedIntValue && highlightSelectedValue
? selectedStyle
: defaultStyle;

return new Center(
child: new Text(
getDisplayedValue(value),
style: itemStyle,
),
);
},
),
_NumberPickerSelectedItemDecoration(
axis: scrollDirection,
itemExtent: itemExtent,
decoration: decoration,
),
],
),
),
onNotification: _onIntegerNotification,
Expand Down Expand Up @@ -470,6 +515,34 @@ class NumberPicker extends StatelessWidget {
}
}

class _NumberPickerSelectedItemDecoration extends StatelessWidget {
final Axis axis;
final double itemExtent;
final Decoration decoration;

const _NumberPickerSelectedItemDecoration(
{Key key,
@required this.axis,
@required this.itemExtent,
@required this.decoration})
: super(key: key);

@override
Widget build(BuildContext context) {
return new Center(
child: new IgnorePointer(
child: new Container(
width: isVertical ? double.infinity : itemExtent,
height: isVertical ? itemExtent : double.infinity,
decoration: decoration,
),
),
);
}

bool get isVertical => axis == Axis.vertical;
}

///Returns AlertDialog as a Widget so it is designed to be used in showDialog method
class NumberPickerDialog extends StatefulWidget {
final int minValue;
Expand All @@ -484,6 +557,8 @@ class NumberPickerDialog extends StatefulWidget {
final int step;
final bool infiniteLoop;
final bool zeroPad;
final bool highlightSelectedValue;
final Decoration decoration;

///constructor for integer values
NumberPickerDialog.integer({
Expand All @@ -495,6 +570,8 @@ class NumberPickerDialog extends StatefulWidget {
this.step = 1,
this.infiniteLoop = false,
this.zeroPad = false,
this.highlightSelectedValue = true,
this.decoration,
Widget confirmWidget,
Widget cancelWidget,
}) : confirmWidget = confirmWidget ?? new Text("OK"),
Expand All @@ -510,6 +587,8 @@ class NumberPickerDialog extends StatefulWidget {
this.decimalPlaces = 1,
this.title,
this.titlePadding,
this.highlightSelectedValue = true,
this.decoration,
Widget confirmWidget,
Widget cancelWidget,
}) : confirmWidget = confirmWidget ?? new Text("OK"),
Expand Down Expand Up @@ -547,6 +626,8 @@ class _NumberPickerDialogControllerState extends State<NumberPickerDialog> {
minValue: widget.minValue,
maxValue: widget.maxValue,
decimalPlaces: widget.decimalPlaces,
highlightSelectedValue: widget.highlightSelectedValue,
decoration: widget.decoration,
onChanged: _handleValueChanged);
} else {
return new NumberPicker.integer(
Expand All @@ -556,6 +637,8 @@ class _NumberPickerDialogControllerState extends State<NumberPickerDialog> {
step: widget.step,
infiniteLoop: widget.infiniteLoop,
zeroPad: widget.zeroPad,
highlightSelectedValue: widget.highlightSelectedValue,
decoration: widget.decoration,
onChanged: _handleValueChanged,
);
}
Expand Down
16 changes: 15 additions & 1 deletion test/integer_infinite_numberpicker_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,18 @@ void main() {
infiniteLoop: true,
expectedDisplayValues: ['09', '10', '00']);
});
}

testWidgets('Decorated number picker works', (WidgetTester tester) async {
await testNumberPicker(
tester: tester,
minValue: 0,
maxValue: 10,
initialValue: 2,
scrollBy: 2,
expectedValue: 4,
infiniteLoop: true,
highlightSelectedValue: false,
decoration: decoration,
);
});
}

0 comments on commit f97281e

Please sign in to comment.