Android NumberPicker OnValueChangeListener
Asked Answered
C

1

6

I have a question concerning the Android NumberPicker. When the user is performing a Fling on a NumberPicker, for every single step the Listener for OnValueChange is triggered. Can I change this in that way, that the oldVal and the newVal can possibly differ by more than 1 from each other and the Listener is only triggered once?

Thanks in advance.

EDIT: I will try to explain it more specific in my code.

        int diff = Math.abs(newVal - oldVal);

        if (newVal - oldVal > 0) {
            sendMessage(te);
            for (int i = 0; i < diff; i++) {
                sendMessage(plus);
            }
            sendMessage(te);
        } else if (newVal - oldVal < 0) {
            sendMessage(te);
            for (int i = 0; i < diff; i++) {
                sendMessage(minus);
            }
            sendMessage(te);
        } else {
            if (D)
                Log.w(TAG, "This should NEVER happen");
        }

This method is called inonValueChange. It sends the Messages too fast for my connected device to react in time. So I need to slow this down in any way. Does anyone has an idea how to slow it, without letting my main Thread sleep? When it is sleeping, the whole GUI is not responding during this time. I try to avoid this.

Thanks.

Cheerly answered 16/5, 2013 at 15:13 Comment(0)
C
13

Instead of setOnValueChangedListener you can use setOnScrollListener, and get the value of your picker when the scroll state is SCROLL_STATE_IDLE. Check this example:

    numberPicker.setOnScrollListener(new NumberPicker.OnScrollListener() {

        private int oldValue;  //You need to init this value.

        @Override
        public void onScrollStateChange(NumberPicker numberPicker, int scrollState) {
            if (scrollState == NumberPicker.OnScrollListener.SCROLL_STATE_IDLE) {
                //We get the different between oldValue and the new value
                int valueDiff = numberPicker.getValue() - oldValue;

                //Update oldValue to the new value for the next scroll
                oldValue = numberPicker.getValue();

                //Do action with valueDiff
            }
        }
    });

Note that you need to init the value for oldValue variable in the listener. If you need to create a generic listener (that can receive any array of values), you can create a custom class that implements NumberPicker.OnScrollListener and receive the initial value in the constructor. Something like this:

    public class MyNumberPickerScrollListener implements NumberPicker.OnScrollListener {

        private int oldValue;

        public MyNumberPickerScrollListener(int initialValue) {
            oldValue = initialValue;
        }

        @Override
        public void onScrollStateChange(NumberPicker numberPicker, int scrollState) {
            if (scrollState == NumberPicker.OnScrollListener.SCROLL_STATE_IDLE) {
                //We get the different between oldValue and the new value
                int valueDiff = numberPicker.getValue() - oldValue;

                //Update oldValue to the new value for the next scroll
                oldValue = numberPicker.getValue();

                //Do action with valueDiff
            }
        }
    }

Read the NumberPicker.onScrollListener documentation for more information.

Chambers answered 16/5, 2013 at 15:47 Comment(3)
This does not yet solve my problem. What i want to do is: As long as it is flinging do nothing. When it stops get the difference between the new value and the value before the fling. Do some function with that value. Additionally I want the same functionality, when the value is only changed by 1 with a click and no fling. I need to send a number of commands, which is as high as the difference, everytime it is changed in any way.Cheerly
See if the updated response fits what you need to implement ;-)Chambers
Added in 2013 , still useful in 2021 also :)Homovec

© 2022 - 2024 — McMap. All rights reserved.