diff --git a/example/lib/main.dart b/example/lib/main.dart index 7cc7a72..aab1b7e 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -63,7 +63,7 @@ class __IntegerExampleState extends State<_IntegerExample> { return Column( children: [ SizedBox(height: 16), - Text('Default', style: Theme.of(context).textTheme.headline6), + Text('Default', style: Theme.of(context).textTheme.titleLarge), NumberPicker( value: _currentIntValue, minValue: 0, @@ -95,7 +95,7 @@ class __IntegerExampleState extends State<_IntegerExample> { ), Divider(color: Colors.grey, height: 32), SizedBox(height: 16), - Text('Horizontal', style: Theme.of(context).textTheme.headline6), + Text('Horizontal', style: Theme.of(context).textTheme.titleLarge), NumberPicker( value: _currentHorizontalIntValue, minValue: 0, @@ -103,8 +103,7 @@ class __IntegerExampleState extends State<_IntegerExample> { step: 10, itemHeight: 100, axis: Axis.horizontal, - onChanged: (value) => - setState(() => _currentHorizontalIntValue = value), + onChanged: (value) => setState(() => _currentHorizontalIntValue = value), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), border: Border.all(color: Colors.black26), @@ -148,7 +147,7 @@ class __DecimalExampleState extends State<_DecimalExample> { return Column( children: [ SizedBox(height: 16), - Text('Decimal', style: Theme.of(context).textTheme.headline6), + Text('Decimal', style: Theme.of(context).textTheme.titleLarge), DecimalNumberPicker( value: _currentDoubleValue, minValue: 0, diff --git a/lib/src/numberpicker.dart b/lib/src/numberpicker.dart index 5b59951..ed1f65a 100644 --- a/lib/src/numberpicker.dart +++ b/lib/src/numberpicker.dart @@ -15,7 +15,7 @@ class NumberPicker extends StatefulWidget { final int value; /// Called when selected value changes - final ValueChanged onChanged; + final ValueChanged? onChanged; /// Specifies how many items should be shown - defaults to 3 final int itemCount; @@ -61,7 +61,7 @@ class NumberPicker extends StatefulWidget { required this.minValue, required this.maxValue, required this.value, - required this.onChanged, + this.onChanged, this.itemCount = 3, this.step = 1, this.itemHeight = 50, @@ -88,11 +88,9 @@ class _NumberPickerState extends State { @override void initState() { super.initState(); - final initialOffset = - (widget.value - widget.minValue) ~/ widget.step * itemExtent; + final initialOffset = (widget.value - widget.minValue) ~/ widget.step * itemExtent; if (widget.infiniteLoop) { - _scrollController = - InfiniteScrollController(initialScrollOffset: initialOffset); + _scrollController = InfiniteScrollController(initialScrollOffset: initialOffset); } else { _scrollController = ScrollController(initialScrollOffset: initialOffset); } @@ -106,19 +104,22 @@ class _NumberPickerState extends State { } else { indexOfMiddleElement = indexOfMiddleElement.clamp(0, itemCount - 1); } - final intValueInTheMiddle = - _intValueFromIndex(indexOfMiddleElement + additionalItemsOnEachSide); + final intValueInTheMiddle = _intValueFromIndex(indexOfMiddleElement + additionalItemsOnEachSide); if (widget.value != intValueInTheMiddle) { - widget.onChanged(intValueInTheMiddle); - if (widget.haptics) { - HapticFeedback.selectionClick(); + if (widget.onChanged != null) { + widget.onChanged!(intValueInTheMiddle); + if (widget.haptics) { + HapticFeedback.selectionClick(); + } } } - Future.delayed( - Duration(milliseconds: 100), - () => _maybeCenterValue(), - ); + if (!isScrolling) { + Future.delayed( + Duration(milliseconds: 100), + () => _maybeCenterValue(), + ); + } } @override @@ -137,8 +138,7 @@ class _NumberPickerState extends State { bool get isScrolling => _scrollController.position.isScrollingNotifier.value; - double get itemExtent => - widget.axis == Axis.vertical ? widget.itemHeight : widget.itemWidth; + double get itemExtent => widget.axis == Axis.vertical ? widget.itemHeight : widget.itemWidth; int get itemCount => (widget.maxValue - widget.minValue) ~/ widget.step + 1; @@ -149,12 +149,8 @@ class _NumberPickerState extends State { @override Widget build(BuildContext context) { return SizedBox( - width: widget.axis == Axis.vertical - ? widget.itemWidth - : widget.itemCount * widget.itemWidth, - height: widget.axis == Axis.vertical - ? widget.itemCount * widget.itemHeight - : widget.itemHeight, + width: widget.axis == Axis.vertical ? widget.itemWidth : widget.itemCount * widget.itemWidth, + height: widget.axis == Axis.vertical ? widget.itemCount * widget.itemHeight : widget.itemHeight, child: NotificationListener( onNotification: (not) { if (not.dragDetails?.primaryVelocity == 0) { @@ -166,6 +162,7 @@ class _NumberPickerState extends State { children: [ if (widget.infiniteLoop) InfiniteListView.builder( + physics: widget.onChanged == null ? NeverScrollableScrollPhysics() : BouncingScrollPhysics(), scrollDirection: widget.axis, controller: _scrollController as InfiniteScrollController, itemExtent: itemExtent, @@ -174,6 +171,7 @@ class _NumberPickerState extends State { ) else ListView.builder( + physics: widget.onChanged == null ? NeverScrollableScrollPhysics() : BouncingScrollPhysics(), itemCount: listItemsCount, scrollDirection: widget.axis, controller: _scrollController, @@ -195,14 +193,12 @@ class _NumberPickerState extends State { Widget _itemBuilder(BuildContext context, int index) { final themeData = Theme.of(context); final defaultStyle = widget.textStyle ?? themeData.textTheme.bodyMedium; - final selectedStyle = widget.selectedTextStyle ?? - themeData.textTheme.headlineSmall - ?.copyWith(color: themeData.colorScheme.secondary); + final selectedStyle = + widget.selectedTextStyle ?? themeData.textTheme.headlineSmall?.copyWith(color: themeData.colorScheme.secondary); final value = _intValueFromIndex(index % itemCount); final isExtra = !widget.infiniteLoop && - (index < additionalItemsOnEachSide || - index >= listItemsCount - additionalItemsOnEachSide); + (index < additionalItemsOnEachSide || index >= listItemsCount - additionalItemsOnEachSide); final itemStyle = value == widget.value ? selectedStyle : defaultStyle; final child = isExtra @@ -221,9 +217,7 @@ class _NumberPickerState extends State { } String _getDisplayedValue(int value) { - final text = widget.zeroPad - ? value.toString().padLeft(widget.maxValue.toString().length, '0') - : value.toString(); + final text = widget.zeroPad ? value.toString().padLeft(widget.maxValue.toString().length, '0') : value.toString(); if (widget.textMapper != null) { return widget.textMapper!(text); } else { diff --git a/pubspec.yaml b/pubspec.yaml index 9c8cd0e..1d43988 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ description: NumberPicker is a widget allowing user to choose numbers by scrolli homepage: https://github.com/MarcinusX/NumberPicker environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.12.0 <4.0.0" dependencies: flutter: