Git Product home page Git Product logo

numberpicker's Introduction

NumberPicker Build Status Coverage Status

NumberPicker is a custom widget designed for choosing an integer or decimal number by scrolling spinners.

ezgif com-gif-maker

Example:

(See example for more)

class _IntegerExample extends StatefulWidget {
  @override
  __IntegerExampleState createState() => __IntegerExampleState();
}

class __IntegerExampleState extends State<_IntegerExample> {
  int _currentValue = 3;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        NumberPicker(
          value: _currentValue,
          minValue: 0,
          maxValue: 100,
          onChanged: (value) => setState(() => _currentValue = value),
        ),
        Text('Current value: $_currentValue'),
      ],
    );
  }
}

numberpicker's People

Contributors

alirn76 avatar bcko avatar boeledi avatar ddmgy avatar hamaluik avatar hugosart avatar insin avatar jmolins avatar kevinthegray avatar marcinusx avatar maskys avatar mathieupost avatar monias avatar pedromassango avatar phanirithvij avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

numberpicker's Issues

Decimal picker crashes when trying to change decimal point

My picker:

return new NumberPickerDialog.decimal( minValue: 37, maxValue: 42, initialDoubleValue: 37.5, );

I did some debugging, looks like in _onDecimalNotification(Notification notification) the decimalValueInTheMiddle is too big (37 in my case). Upon closer looking I am actually confused what the purpose of that variable is.

The relevant problem happens towards the end:

double newValue = ((selectedIntValue + decimalPart).toDouble());

The decimal part in my case is 3.7 (gets formed from the 37 I mentioned above). If I understand that correctly, the decimal part should be between 0(inclusive) and 1(exclusive).

In my case the newValue becomes too big at some point which is why the number picker craps out with an assertion error from the constructor (min max selected check)

Exception:

I/flutter (12075): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (12075): The following assertion was thrown building NumberPickerDialog(dirty, state:
I/flutter (12075): _NumberPickerDialogControllerState#2927b):
I/flutter (12075): 'package:numberpicker/numberpicker.dart': Failed assertion: line 58 pos 16: 'initialValue >=
I/flutter (12075): minValue && initialValue <= maxValue': is not true.
I/flutter (12075):
I/flutter (12075): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (12075): more information in this error message to help you determine and fix the underlying cause.
I/flutter (12075): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (12075): https://github.com/flutter/flutter/issues/new
I/flutter (12075):
I/flutter (12075): When the exception was thrown, this was the stack:
I/flutter (12075): #2 new NumberPicker.decimal (package:numberpicker/numberpicker.dart)
I/flutter (12075): #3 _NumberPickerDialogControllerState._buildNumberPicker (package:numberpicker/numberpicker.dart:396:18)
I/flutter (12075): #4 _NumberPickerDialogControllerState.build (package:numberpicker/numberpicker.dart:417:16)
I/flutter (12075): #5 StatefulElement.build (package:flutter/src/widgets/framework.dart:3730:27)
I/flutter (12075): #6 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3642:15)
I/flutter (12075): #7 Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
I/flutter (12075): #8 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2242:33)
I/flutter (12075): #9 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:626:20)
I/flutter (12075): #10 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:208:5)
I/flutter (12075): #11 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
I/flutter (12075): #12 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
I/flutter (12075): #13 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
I/flutter (12075): #14 _invoke (dart:ui/hooks.dart:120:13)
I/flutter (12075): #15 _drawFrame (dart:ui/hooks.dart:109:3)
I/flutter (12075): (elided 2 frames from class _AssertionError)
I/flutter (12075): ════════════════════════════════════════════════════════════════════════════════════════════════════

Background Color

It would be nice to give it whatever background color we would like!

Step equal to 10 breaks on iOS emulator

NumberPicker worked fine until I installed:

Flutter 0.7.3 • channel beta • https://github.com/flutter/flutter.git
Framework • revision 3b309bda07 (8 days ago) • 2018-08-28 12:39:24 -0700
Engine • revision af42b6dc95
Tools • Dart 2.1.0-dev.1.0.flutter-ccb16f7282

Now at least in the iOS emulator it does not seem to properly handle the 'mouse up' event when attempting to scroll.

Exception when use NumberPickerDialog.integer()

Hi,

Thanks for that lib!

I used the NumberPickerDialog in my code.
After select the number and press ok It shows error in console:

E/flutter (28635): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 150 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.
E/flutter (28635): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:42:39)
E/flutter (28635): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:38:5)
E/flutter (28635): #2 ScrollController.animateTo (package:flutter/src/widgets/scroll_controller.dart:150:12)
E/flutter (28635): #3 NumberPicker._animate (package:numberpicker/numberpicker.dart:561:22)
E/flutter (28635): #4 NumberPicker.animateIntToIndex (package:numberpicker/numberpicker.dart:202:5)
E/flutter (28635): #5 NumberPicker.animateInt (package:numberpicker/numberpicker.dart:197:5)
E/flutter (28635): #6 _TimerSettings._showIntDialog. (package:intervaltimer/screens/settings/timer_settings_page.dart:69:29)
E/flutter (28635): #7 _rootRunUnary (dart:async/zone.dart:1134:38)
E/flutter (28635): #8 _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter (28635): #9 _FutureListener.handleValue (dart:async/future_impl.dart:140:18)
E/flutter (28635): #10 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:682:45)
E/flutter (28635): #11 Future._propagateToListeners (dart:async/future_impl.dart:711:32)
E/flutter (28635): #12 Future._completeWithValue (dart:async/future_impl.dart:526:5)
E/flutter (28635): #13 Future._asyncComplete. (dart:async/future_impl.dart:556:7)
E/flutter (28635): #14 _rootRun (dart:async/zone.dart:1126:13)
E/flutter (28635): #15 _CustomZone.run (dart:async/zone.dart:1023:19)
E/flutter (28635): #16 _CustomZone.runGuarded (dart:async/zone.dart:925:7)
E/flutter (28635): #17 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:965:23)
E/flutter (28635): #18 _microtaskLoop (dart:async/schedule_microtask.dart:43:21)
E/flutter (28635): #19 _startMicrotaskLoop (dart:async/schedule_microtask.dart:52:5)
E/flutter (28635):

No call to onChanged when value == initialValue

In case during the selection process you want to synchronize the value with another Widget (such as a Text), it should be convenient to also have a call to onChanged even if the current value == initialValue.

This could easily be solved by adding another option (e.g. bool forceOnChanged - default false). If set to true, onChanged would be called in all circumstances.

Add number prefix and posfix text

It would be nice if we had the option to customize the number text, For example, write "days" after the number:

...
2 days
3 days
4 days
...

Change color of numbers

Hi,

I tried to change color of all numbers, I achieved to change accentColor using Theme -> data: x.copyWith(), but only change "the selected number", what can I do ?

Thanks

Add step for decimal

Hi,

Thanks you for your work,

Would it be possible to add the steps to the decimals ? I would like to have 0.25/0.5/0.75 for example, with a step of 0.25.

time format

hello, I tried to make a number picker with one column for hour and an other for minutes. I don't see how I can make a maxlimite to the decimal. currently decimal is 0 to 99, I want 0 to 60.

thank you

Adding support for displaying more than 3 numbers at a time

I am looking into displaying more than 3 numbers and have not found any solutions for this. I started seeing if I could do this by making modifications to the numberpicker class. I am exploring specifically for horizontal, but I think it would work both ways.

So far I have managed this by allowing list view width to be passed into the constructor so setting listViewWidth = 7 * itemExtent, gives this

image

As others have noted (#60 and on stackoverflow) this results in some issues. These issues seem to be coming from the intValueInTheMiddle and other logic for highlighting the middle number and also preventing the max number from being highlighted.

  bool _onIntegerNotification(Notification notification) {
    if (notification is ScrollNotification) {
      //calculate
      int intIndexOfMiddleElement =
      (notification.metrics.pixels / itemExtent).round();
      if (!infiniteLoop) {
        intIndexOfMiddleElement =
            intIndexOfMiddleElement.clamp(0, integerItemCount - 1);
      }
      int intValueInTheMiddle = _intValueFromIndex(intIndexOfMiddleElement + 1);
      intValueInTheMiddle = _normalizeIntegerMiddleValue(intValueInTheMiddle);

I am going to be looking into this some more, but wanted to post this here in case anyone had any pointers or thoughts on this approach. It seems to me that this should be doable as it is a matter of tweaking the intValueInTheMiddle and selection logic to work with an adaptable length.

Below is my tweak to the constructor for increasing past 3 numbers as shown above:

  NumberPicker.horizontal({
        Key key,
        @required int initialValue,
        @required this.minValue,
        @required this.maxValue,
        @required this.onChanged,
        this.textMapper,
        this.itemExtent = kDefaultItemExtent,
        this.listViewHeight = kDefaultListViewCrossAxisSize,
        double listViewWidth,
        this.step = 1,
        this.zeroPad = false,
        this.highlightSelectedValue = true,
        this.decoration,
  })  : assert(initialValue != null),
                assert(minValue != null),
                assert(maxValue != null),
                assert(maxValue > minValue),
                assert(initialValue >= minValue && initialValue <= maxValue),
                assert(step > 0),
                selectedIntValue = initialValue,
                selectedDecimalValue = -1,
                decimalPlaces = 0,
                intScrollController = new ScrollController(
                  initialScrollOffset: (initialValue - minValue) ~/ step * itemExtent,
                ),
                scrollDirection = Axis.horizontal,
                decimalScrollController = null,
                listViewWidth = listViewWidth ?? 3 * itemExtent,
                infiniteLoop = false,
                integerItemCount = (maxValue - minValue) ~/ step + 1,
                super(key: key);

not support locale?

NumberPickerDialog.integer( minValue: 1, maxValue: 30, initialIntegerValue: 7, locale: Locale('zh') )

Some Possible improvements to be made

  1. Scroll direction horizontal not working with infinite scroll.
  2. I wanted to show more then 3 numbers , i could show on horizontal scroll by setting listViewWidth and itemExtent but always second index is selected in spite of number in the center
  3. Tapping number to scroll would be cool for selection.
  4. Last and first item selection will be good feature.

Capture2

Selected Values Not Highighted

I am trying to incorporate you widget into my library. When a user designates an integer with a min and max value, I would like to return a number picker:

    if (fieldOptions != null) {
      if (fieldOptions["min"] != null && fieldOptions["max"] != null) {
        int value;
        int iv;
        initialValue == null ? iv = fieldOptions["min"] : iv = initialValue;
        return FormField(
          builder: (FormFieldState<int> state) {
            return NumberPicker.integer(
              initialValue: iv,
              maxValue: fieldOptions["max"],
              minValue: fieldOptions["min"],
              onChanged: (num val) {
                value = val;
              },
            );
          },
          onSaved: (int val) {
            this.onSaved(value);
          },
        );
      }
    }

The widget works perfectly in the form, except that the selected number is not highlighted except on first run.

Here is the branch where I am working on this for reference:
https://github.com/rapido-mobile/rapido-flutter/blob/field_options/lib/src/typed_input_field.dart

Add property for number of values between min and max value

It would be good if we can provide number of values between minimum value and maximum value.
For example , I have a range from 100 to 500 and I want to display only values that are multiple of 100, instead of the usual increment of 1.

Horizontal number picker

Hi,

I would really like to see a scrollDirection property that when set to horizontal we can get a horizonal number picker.

Thanks for a great plugin!

A RenderFlex overflowed by 8.0 pixels on the right.

Overflow of 8px on 3.7 inch screen.
Any suggestions please ... tried SizedBox but not successful.

  • otherwise NumberPicker works very well .. . excellent piece of work - thanks all.

/try Example code from github and suggested SizedBox wrap solution to overflow....
double _currentPrice = 1.0;

void _showDialog() {
showDialog(
context: context,
builder: (BuildContext context) {

    return  SizedBox (
       // width: 200, // fail Overflow 8px
        width: 30, // fail overflow 8px
      child: new NumberPickerDialog.decimal(
        minValue: 1,
        maxValue: 10,
        title: new Text("Pick a new price"),
        initialDoubleValue: _currentPrice,
      )
    );
    }
).then((double value) {
  if (value != null) {
    setState(() => _currentPrice = value);
  }
});

}

Screenshot_1577164344

Add TextStyles for NumberPicker

Is it possible to add an option to supply custom TextStyles? I know that number picker picks the TextStyles from ThemeData.

Choose number not only by scrolling but also by tapping a visible number

Hey there,

first of all: good job!

I have a recommendation for improvement.
At the moment new values are selected by scrolling the numbers in the widget. It would be very helpful, if we could also tap on the next or previous visible number to select it.

For example, if I have 5 selected, then above is 4 and below the selected 5 is the 6. If I could just tap on the 4 to select it would help because then you wouldn't need to scroll just a tiny bit.

Do you think this is possible?

Thanks in advance,

Tobi

Bug in NumberPicker.horizontal

I can't select the last 3 items. constantly rolls back.

Example:
ezgif-1-337adf32a651

Code for reproduce:

NumberPicker.horizontal(
  initialValue: 5,
  minValue: 1,
  maxValue: 10,
  onChanged: (num newValue) {
    // save
  },
)

Padding numbers in integer picker

Would it be possible to add some configuration for integer pickers to zero-pad the numbers displayed in the generated list items?

I have a dialog widget which uses a pair of NumberPicker.integers to select minutes and seconds and gives you back a Duration object, which currently looks like this:

qemu-system-x86_64_2019-02-02_03-26-04

It would be nice to be able to pad the numbers less than 10 out with a zero so they match the way minutes and seconds are displayed elsewhere in the app, e.g. 00 : 09 in the example above.

Cancel and Confirm

How do I check if cancel and confirm?

I want to await the widget and if I press ok I want to keep doing the logic and if the user press cancel I want to stop the logic (with bool or something like that). But the cancel and confirm takes a widget. Why can I just not set logic in this?

I want to do something like this:

image

Crash when overscroll on iOS

When there is a minValue of 3 and a maxValue of 10 (for example) and you overscroll the min or the max you will have a crash on iOS.

Stack trace:

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building NumberPickerDialog(dirty, state:
_NumberPickerDialogControllerState#266d1):
'package:numberpicker/numberpicker.dart': Failed assertion: line 31 pos 16: 'initialValue >=
minValue && initialValue <= maxValue': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially
more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new
When the exception was thrown, this was the stack:
#2      new NumberPicker.integer (package:numberpicker/numberpicker.dart)
#3      _NumberPickerDialogControllerState._buildNumberPicker (package:numberpicker/numberpicker.dart:383:18)
#4      _NumberPickerDialogControllerState.build (package:numberpicker/numberpicker.dart:397:16)
#5      StatefulElement.build (package:flutter/src/widgets/framework.dart:3730:27)
#6      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3642:15)
#7      Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
#8      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2242:33)

Scrollback to middle will break at certain senario.

I found out that If HoldScrollActivity is the final state, the scroller would not go back to middle. The following action could reproduce the issue:

  1. Scroll your wheel hardly.
  2. Just put your finger on wheel and Don't move.
  3. Leave your finger.

The code debugging:

  bool _userStoppedScrolling(Notification notification,
      ScrollController scrollController) {
    print("${notification} ${scrollController.position.activity}");
    return notification is UserScrollNotification &&
        notification.direction == ScrollDirection.idle &&
        scrollController.position.activity is! HoldScrollActivity;
  }

This is the final line of my action with debug result:

UserScrollNotification(depth: 0 (local), FixedScrollMetrics(Infinity..[200.0]..Infinity), direction: ScrollDirection.idle) HoldScrollActivity#05e8e

Edit:
The above code is tested on InfiniteListView, because I want to use infinite feature.

numbers alignment problem

The replicate the problem do this:
slide the picker to search for a number, but click on it while is rolling and it will stop wherever it is at that moment and misalign the number. I think that after that click it should automatically go and align to the nearest number.

textMapper

Can you please give me a hint or code to use textMapper?
I want to achieve some things like this.

image

Values doesn't match between picker and onchanged

That's my code snippet. When I change the value due scrolling, the first number does only the change and when i use the decimal Value it alway jumps back to the inital value( first digit).

` NumberPicker.decimal(

            decoration: BoxDecoration(
              backgroundBlendMode: BlendMode.modulate,
              color: shinyColor,
            ),
            highlightSelectedValue: false,
            initialValue: fieldData.amount,
            minValue: 0,
            maxValue: 6,
            onChanged: (newValue) {
              print(newValue);
              _controllerAmount.sink.add(newValue);
              fieldData.amount = newValue;
            },
          ),
          Padding(
            padding: EdgeInsets.only(top: 10),
            child: StreamBuilder(
              stream: streamAmount,
              initialData: fieldData.amount,
              builder: (context, snapshot) => Text(
                '${snapshot.requireData} to/ha',
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
              ),
            ),
          ),
        ],
      ),
    ),`

Picker UI not being correctly redraw once initialValue property gets updated

I'm experiencing the following issue:

  • In my model I set intialValue default to 1 (this property is mapped to the initialValue property of the picker widget)
  • In my widget builder method I call an async method that will load some data and update this initialValue property
  • I call notifyListeners/setState after the initialValue has been updated (async method finished)
  • the picker widget is redraw but the "current" value is still the old one, we see that the value has been changed because is not green anymore, meaning that it took the new value but it didn't displayed correctly (see screenshot below)

Without calling the async method, initialValue defaults to one (in green):
image

When calling the async method and the intialValue changed to 6, the UI doesn't reflect the new value:
image

Thanks

Document how to test NumberPicker in a widget test

I want to be able to create a test which taps on particular values in the numberpicker and checks to make sure they have the intended effect.

How can I scroll the relevant number into view and then tap it?

I don't want to just call the onChanged callback myself.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.