Skip to content

Commit

Permalink
Solved decimal numbers normalization MarcinusX#16.
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcinusX committed Jun 1, 2018
1 parent e4cabc2 commit 22f0d13
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 36 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## [0.1.4]
* Solved normalizing decimal places bug

## [0.1.3]

* Fixed issue with small integer ranges
Expand Down
75 changes: 40 additions & 35 deletions lib/numberpicker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ class NumberPicker extends StatelessWidget {
@required this.onChanged,
this.itemExtent = DEFAULT_ITEM_EXTENT,
this.listViewWidth = DEFUALT_LISTVIEW_WIDTH,
})
: assert(initialValue != null),
}) : assert(initialValue != null),
assert(minValue != null),
assert(maxValue != null),
assert(maxValue > minValue),
Expand All @@ -49,24 +48,23 @@ class NumberPicker extends StatelessWidget {
this.decimalPlaces = 1,
this.itemExtent = DEFAULT_ITEM_EXTENT,
this.listViewWidth = DEFUALT_LISTVIEW_WIDTH,
})
: assert(initialValue != null),
}) : assert(initialValue != null),
assert(minValue != null),
assert(maxValue != null),
assert(decimalPlaces != null && decimalPlaces > 0),
assert(maxValue > minValue),
assert(initialValue >= minValue && initialValue <= maxValue),
selectedIntValue = initialValue.floor(),
selectedDecimalValue = ((initialValue - initialValue.floorToDouble()) *
math.pow(10, decimalPlaces))
math.pow(10, decimalPlaces))
.round(),
intScrollController = new ScrollController(
initialScrollOffset: (initialValue.floor() - minValue) * itemExtent,
),
decimalScrollController = new ScrollController(
initialScrollOffset: ((initialValue - initialValue.floorToDouble()) *
math.pow(10, decimalPlaces))
.roundToDouble() *
math.pow(10, decimalPlaces))
.roundToDouble() *
itemExtent,
),
_listViewHeight = 3 * itemExtent,
Expand Down Expand Up @@ -121,7 +119,7 @@ class NumberPicker extends StatelessWidget {
animateDecimalAndInteger(double valueToSelect) {
animateInt(valueToSelect.floor());
animateDecimal(((valueToSelect - valueToSelect.floorToDouble()) *
math.pow(10, decimalPlaces))
math.pow(10, decimalPlaces))
.round());
}

Expand Down Expand Up @@ -150,7 +148,7 @@ class NumberPicker extends StatelessWidget {
Widget _integerListView(ThemeData themeData) {
TextStyle defaultStyle = themeData.textTheme.body1;
TextStyle selectedStyle =
themeData.textTheme.headline.copyWith(color: themeData.accentColor);
themeData.textTheme.headline.copyWith(color: themeData.accentColor);

int itemCount = maxValue - minValue + 3;

Expand All @@ -168,15 +166,15 @@ class NumberPicker extends StatelessWidget {

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

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

return isExtra
? new Container() //empty first and last element
: new Center(
child: new Text(value.toString(), style: itemStyle),
);
child: new Text(value.toString(), style: itemStyle),
);
},
),
),
Expand All @@ -187,10 +185,10 @@ class NumberPicker extends StatelessWidget {
Widget _decimalListView(ThemeData themeData) {
TextStyle defaultStyle = themeData.textTheme.body1;
TextStyle selectedStyle =
themeData.textTheme.headline.copyWith(color: themeData.accentColor);
themeData.textTheme.headline.copyWith(color: themeData.accentColor);

int itemCount =
selectedIntValue == maxValue ? 3 : math.pow(10, decimalPlaces) + 2;
selectedIntValue == maxValue ? 3 : math.pow(10, decimalPlaces) + 2;

return new NotificationListener(
child: new Container(
Expand All @@ -205,17 +203,17 @@ class NumberPicker extends StatelessWidget {

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

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

return isExtra
? new Container() //empty first and last element
: new Center(
child: new Text(
value.toString().padLeft(decimalPlaces, '0'),
style: itemStyle),
);
child: new Text(
value.toString().padLeft(decimalPlaces, '0'),
style: itemStyle),
);
},
),
),
Expand All @@ -233,7 +231,7 @@ class NumberPicker extends StatelessWidget {
int intIndexOfMiddleElement =
(notification.metrics.pixels + _listViewHeight / 2) ~/ itemExtent;
int intValueInTheMiddle = minValue + intIndexOfMiddleElement - 1;
intValueInTheMiddle = _normalizeMiddleValue(intValueInTheMiddle);
intValueInTheMiddle = _normalizeIntegerMiddleValue(intValueInTheMiddle);

if (_userStoppedScrolling(notification, intScrollController)) {
//center selected value
Expand Down Expand Up @@ -269,7 +267,8 @@ class NumberPicker extends StatelessWidget {
int indexOfMiddleElement =
(notification.metrics.pixels + _listViewHeight / 2) ~/ itemExtent;
int decimalValueInTheMiddle = indexOfMiddleElement - 1;
decimalValueInTheMiddle = _normalizeMiddleValue(decimalValueInTheMiddle);
decimalValueInTheMiddle =
_normalizeDecimalMiddleValue(decimalValueInTheMiddle);

if (_userStoppedScrolling(notification, decimalScrollController)) {
//center selected value
Expand Down Expand Up @@ -301,13 +300,22 @@ class NumberPicker extends StatelessWidget {
///When overscroll occurs on iOS,
///we can end up with value not in the range between [minValue] and [maxValue]
///To avoid going out of range, we change values out of range to border values.
int _normalizeMiddleValue(int valueInTheMiddle) {
return math.max(math.min(valueInTheMiddle, maxValue), minValue);
int _normalizeMiddleValue(int valueInTheMiddle, int min, int max) {
return math.max(math.min(valueInTheMiddle, max), min);
}

int _normalizeIntegerMiddleValue(int integerValueInTheMiddle) {
return _normalizeMiddleValue(integerValueInTheMiddle, minValue, maxValue);
}

int _normalizeDecimalMiddleValue(int decimalValueInTheMiddle) {
return _normalizeMiddleValue(
decimalValueInTheMiddle, 0, math.pow(10, decimalPlaces) - 1);
}

///indicates if user has stopped scrolling so we can center value in the middle
bool _userStoppedScrolling(Notification notification,
ScrollController scrollController) {
bool _userStoppedScrolling(
Notification notification, ScrollController scrollController) {
return notification is UserScrollNotification &&
notification.direction == ScrollDirection.idle &&
scrollController.position.activity is! HoldScrollActivity;
Expand Down Expand Up @@ -349,8 +357,7 @@ class NumberPickerDialog extends StatefulWidget {
this.titlePadding,
Widget confirmWidget,
Widget cancelWidget,
})
: confirmWidget = confirmWidget ?? new Text("OK"),
}) : confirmWidget = confirmWidget ?? new Text("OK"),
cancelWidget = cancelWidget ?? new Text("CANCEL"),
decimalPlaces = 0,
initialDoubleValue = -1.0;
Expand All @@ -365,8 +372,7 @@ class NumberPickerDialog extends StatefulWidget {
this.titlePadding,
Widget confirmWidget,
Widget cancelWidget,
})
: confirmWidget = confirmWidget ?? new Text("OK"),
}) : confirmWidget = confirmWidget ?? new Text("OK"),
cancelWidget = cancelWidget ?? new Text("CANCEL"),
initialIntegerValue = -1;

Expand All @@ -380,8 +386,8 @@ class _NumberPickerDialogControllerState extends State<NumberPickerDialog> {
int selectedIntValue;
double selectedDoubleValue;

_NumberPickerDialogControllerState(this.selectedIntValue,
this.selectedDoubleValue);
_NumberPickerDialogControllerState(
this.selectedIntValue, this.selectedDoubleValue);

_handleValueChanged(num value) {
if (value is int) {
Expand Down Expand Up @@ -421,10 +427,9 @@ class _NumberPickerDialogControllerState extends State<NumberPickerDialog> {
child: widget.cancelWidget,
),
new FlatButton(
onPressed: () =>
Navigator.of(context).pop(widget.decimalPlaces > 0
? selectedDoubleValue
: selectedIntValue),
onPressed: () => Navigator.of(context).pop(widget.decimalPlaces > 0
? selectedDoubleValue
: selectedIntValue),
child: widget.confirmWidget),
],
);
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: numberpicker
version: 0.1.3
version: 0.1.4
description: NumberPicker is a widget allowing user to choose numbers by scrolling spinners.
author: Marcin Szalek <[email protected]>
homepage: https://github.com/MarcinusX/NumberPicker
Expand Down

0 comments on commit 22f0d13

Please sign in to comment.