Skip to content

Commit

Permalink
Added odd number support for odd numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
lzhuor committed May 24, 2020
1 parent f84c33e commit a695958
Showing 1 changed file with 62 additions and 56 deletions.
118 changes: 62 additions & 56 deletions lib/numberpicker.dart
Expand Up @@ -6,7 +6,6 @@ import 'package:flutter/rendering.dart';
import 'package:infinite_listview/infinite_listview.dart';

/// Created by Marcin Szałek
///Define a text mapper to transform the text displayed by the picker
typedef String TextMapper(String numberText);

Expand All @@ -30,6 +29,7 @@ class NumberPicker extends StatelessWidget {
this.textMapper,
this.itemExtent = kDefaultItemExtent,
this.listViewHeight = kDefaultListViewCrossAxisSize,
this.numberToDisplay = 5,
this.step = 1,
this.zeroPad = false,
this.highlightSelectedValue = true,
Expand All @@ -44,11 +44,11 @@ class NumberPicker extends StatelessWidget {
selectedDecimalValue = -1,
decimalPlaces = 0,
intScrollController = new ScrollController(
initialScrollOffset: (initialValue - minValue) ~/ step * itemExtent,
initialScrollOffset: (initialValue - minValue) ~/ step * itemExtent, //eg 1-10, start 5: (5-1)/1*50=4*50=200
),
scrollDirection = Axis.horizontal,
decimalScrollController = null,
listViewWidth = 3 * itemExtent,
listViewWidth = numberToDisplay * itemExtent,
infiniteLoop = false,
integerItemCount = (maxValue - minValue) ~/ step + 1,
super(key: key);
Expand All @@ -63,6 +63,7 @@ class NumberPicker extends StatelessWidget {
this.textMapper,
this.itemExtent = kDefaultItemExtent,
this.listViewWidth = kDefaultListViewCrossAxisSize,
this.numberToDisplay = 5,
this.step = 1,
this.scrollDirection = Axis.vertical,
this.infiniteLoop = false,
Expand All @@ -81,15 +82,15 @@ class NumberPicker extends StatelessWidget {
decimalPlaces = 0,
intScrollController = infiniteLoop
? new InfiniteScrollController(
initialScrollOffset:
(initialValue - minValue) ~/ step * itemExtent,
)
initialScrollOffset:
(initialValue - minValue) ~/ step * itemExtent,
)
: new ScrollController(
initialScrollOffset:
(initialValue - minValue) ~/ step * itemExtent,
),
initialScrollOffset:
(initialValue - minValue) ~/ step * itemExtent,
),
decimalScrollController = null,
listViewHeight = 3 * itemExtent,
listViewHeight = numberToDisplay * itemExtent,
integerItemCount = (maxValue - minValue) ~/ step + 1,
super(key: key);

Expand All @@ -104,6 +105,7 @@ class NumberPicker extends StatelessWidget {
this.decimalPlaces = 1,
this.itemExtent = kDefaultItemExtent,
this.listViewWidth = kDefaultListViewCrossAxisSize,
this.numberToDisplay = 3,
this.highlightSelectedValue = true,
this.decoration,
}) : assert(initialValue != null),
Expand All @@ -114,18 +116,18 @@ class NumberPicker extends StatelessWidget {
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,
listViewHeight = numberToDisplay * itemExtent,
step = 1,
scrollDirection = Axis.vertical,
integerItemCount = maxValue.floor() - minValue.floor() + 1,
Expand All @@ -141,7 +143,7 @@ class NumberPicker extends StatelessWidget {

///max value user can pick
final int maxValue;

///build the text of each item on the picker
final TextMapper textMapper;

Expand All @@ -158,6 +160,9 @@ class NumberPicker extends StatelessWidget {
///width of list view in pixels
final double listViewWidth;

///number of numbers displayed at any one time
final int numberToDisplay;

///ScrollController used for integer list
final ScrollController intScrollController;

Expand Down Expand Up @@ -220,7 +225,7 @@ class NumberPicker extends StatelessWidget {
void animateDecimalAndInteger(double valueToSelect) {
animateInt(valueToSelect.floor());
animateDecimal(((valueToSelect - valueToSelect.floorToDouble()) *
math.pow(10, decimalPlaces))
math.pow(10, decimalPlaces))
.round());
}

Expand Down Expand Up @@ -250,11 +255,11 @@ class NumberPicker extends StatelessWidget {
}

Widget _integerListView(ThemeData themeData) {
TextStyle defaultStyle = themeData.textTheme.body1;
TextStyle defaultStyle = themeData.textTheme.bodyText2;
TextStyle selectedStyle =
themeData.textTheme.headline.copyWith(color: themeData.accentColor);
themeData.textTheme.headline5.copyWith(color: themeData.accentColor);

var listItemCount = integerItemCount + 2;
var listItemCount = integerItemCount + numberToDisplay - 1; //3=>2, 7=>6, etc.

return Listener(
onPointerUp: (ev) {
Expand All @@ -280,20 +285,20 @@ class NumberPicker extends StatelessWidget {

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

bool isExtra = index == 0 || index == listItemCount - 1;
bool isExtra = index <= numberToDisplay~/2 - 1 || index >= listItemCount - (numberToDisplay~/2); //index == 0 || index == listItemCount - 1; 7: <=4 and >= 6-5 = 1

return isExtra
? new Container() //empty first and last element
: new Center(
child: new Text(
getDisplayedValue(value),
style: itemStyle,
),
);
child: new Text(
getDisplayedValue(value),
style: itemStyle,
),
);
},
),
_NumberPickerSelectedItemDecoration(
Expand All @@ -310,12 +315,12 @@ class NumberPicker extends StatelessWidget {
}

Widget _decimalListView(ThemeData themeData) {
TextStyle defaultStyle = themeData.textTheme.body1;
TextStyle defaultStyle = themeData.textTheme.bodyText2;
TextStyle selectedStyle =
themeData.textTheme.headline.copyWith(color: themeData.accentColor);
themeData.textTheme.headline.copyWith(color: themeData.accentColor);

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

return Listener(
onPointerUp: (ev) {
Expand All @@ -339,19 +344,19 @@ class NumberPicker extends StatelessWidget {

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

bool isExtra = index == 0 || index == decimalItemCount - 1;
bool isExtra = index <= numberToDisplay-2 || index >= decimalItemCount - (numberToDisplay-2); //empty elements determined based on number to display

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),
);
},
),
_NumberPickerSelectedItemDecoration(
Expand All @@ -370,7 +375,7 @@ class NumberPicker extends StatelessWidget {
Widget _integerInfiniteListView(ThemeData themeData) {
TextStyle defaultStyle = themeData.textTheme.body1;
TextStyle selectedStyle =
themeData.textTheme.headline.copyWith(color: themeData.accentColor);
themeData.textTheme.headline.copyWith(color: themeData.accentColor);

return Listener(
onPointerUp: (ev) {
Expand All @@ -393,9 +398,9 @@ class NumberPicker extends StatelessWidget {

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

return new Center(
child: new Text(
Expand Down Expand Up @@ -430,7 +435,7 @@ class NumberPicker extends StatelessWidget {
//

int _intValueFromIndex(int index) {
index--;
index = index - (numberToDisplay~/2); //index--; //for extra elements. 3=>1, 7=>3
index %= integerItemCount;
return minValue + index * step;
}
Expand All @@ -439,12 +444,13 @@ class NumberPicker extends StatelessWidget {
if (notification is ScrollNotification) {
//calculate
int intIndexOfMiddleElement =
(notification.metrics.pixels / itemExtent).round();
(notification.metrics.pixels / itemExtent).round();
if (!infiniteLoop) {
intIndexOfMiddleElement =
intIndexOfMiddleElement.clamp(0, integerItemCount - 1);
intIndexOfMiddleElement.clamp(0, integerItemCount - 1); //integerItemCount - numberToDisplay~/2
}
int intValueInTheMiddle = _intValueFromIndex(intIndexOfMiddleElement + 1);
int intValueInTheMiddle = _intValueFromIndex(intIndexOfMiddleElement + numberToDisplay~/2); //3=> +1, 5=> +2, 7=> +3

intValueInTheMiddle = _normalizeIntegerMiddleValue(intValueInTheMiddle);

if (_userStoppedScrolling(notification, intScrollController)) {
Expand Down Expand Up @@ -505,7 +511,7 @@ class NumberPicker extends StatelessWidget {
///To prevent this we are calculating cacheExtent by our own so it gets smaller if number of items is smaller
double _calculateCacheExtent(int itemCount) {
double cacheExtent = 250.0; //default cache extent
if ((itemCount - 2) * kDefaultItemExtent <= cacheExtent) {
if ((itemCount - 2) * kDefaultItemExtent <= cacheExtent) { //(count-2)*50<=250, count<=23
cacheExtent = ((itemCount - 3) * kDefaultItemExtent);
}
return cacheExtent;
Expand All @@ -531,9 +537,9 @@ class NumberPicker extends StatelessWidget {

///indicates if user has stopped scrolling so we can center value in the middle
bool _userStoppedScrolling(
Notification notification,
ScrollController scrollController,
) {
Notification notification,
ScrollController scrollController,
) {
return notification is UserScrollNotification &&
notification.direction == ScrollDirection.idle &&
scrollController.position.activity is! HoldScrollActivity;
Expand Down Expand Up @@ -569,7 +575,7 @@ class NumberPicker extends StatelessWidget {
///scroll to selected value
_animate(ScrollController scrollController, double value) {
scrollController.animateTo(value,
duration: new Duration(seconds: 1), curve: new ElasticOutCurve());
duration: new Duration(milliseconds: 500), curve: new ElasticOutCurve());
}
}

Expand All @@ -580,9 +586,9 @@ class _NumberPickerSelectedItemDecoration extends StatelessWidget {

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

@override
Expand Down Expand Up @@ -721,4 +727,4 @@ class _NumberPickerDialogControllerState extends State<NumberPickerDialog> {
],
);
}
}
}

0 comments on commit a695958

Please sign in to comment.