Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Number picker with custom values shows wrong data when tapping on it

I have this problem only on android 4+. When I try on lower versions it seems to work ok.

I want to make a number picker in the range from -30 to 30.

I try to do it this way:

mypicker = (NumberPicker) findViewById(R.id.picker);

String[] values = new String[61];

    for (int i = 0; i < 61; i++) {
        int value = 30 - i;
        values[i] = (value >= 0 ? "+ " : "- ") + Integer.toString(Math.abs(value));
    }

    mypicker.setMinValue(0);
    mypicker.setMaxValue(60);
    mypicker.setDisplayedValues(values);
    mypicker.setDescendantFocusability(TimePicker.FOCUS_BLOCK_DESCENDANTS);

    mypicker.setValue(30 - myValue); 

And it works except one strange thing. When I select 1, 2 or 3 and then tap on the selected value several times, it changes +1 to +19, +2 to +29 and +3 to +30. All other numbers work ok.

Can anyone help me with this? I really don’t know why this happens and can’t google any answers.

mypicker

like image 558
Anastasiia Chervinska Avatar asked Feb 25 '26 22:02

Anastasiia Chervinska


1 Answers

I am seeing the same issue. I am implementing a custom time picker with minute values in 5 minute increments (which cannot be done with stock time picker as far as I can tell.)

For the left hand picker I initialize display values as: "12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"

If I set the value to 1 ("1") and tap on it, it toggles between "12" and "1". I have analyzed the NumberPicker.onTouch code and I see this:

    case MotionEvent.ACTION_UP: {
        removeBeginSoftInputCommand();
        removeChangeCurrentByOneFromLongPress();
        mPressedStateHelper.cancel();
        VelocityTracker velocityTracker = mVelocityTracker;
        velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
        int initialVelocity = (int) velocityTracker.getYVelocity();
        if (Math.abs(initialVelocity) > mMinimumFlingVelocity) {
            fling(initialVelocity);
            onScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
        } else {
            int eventY = (int) event.getY();
            int deltaMoveY = (int) Math.abs(eventY - mLastDownEventY);
            long deltaTime = event.getEventTime() - mLastDownEventTime;
            if (deltaMoveY <= mTouchSlop && deltaTime < ViewConfiguration.getTapTimeout()) {
                if (mShowSoftInputOnTap) {
                    mShowSoftInputOnTap = false;
                    showSoftInput();
                } else {

My theory is that the showSoftInput method is the culprit. I can find no way to prevent showSoftInput except by override the onTouch method. So I created a derived class to test:

public class FPNumberPicker extends NumberPicker {

    public FPNumberPicker(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public FPNumberPicker(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FPNumberPicker(Context context) {
        super(context);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_UP: {
                return false;
            } 
        }
        return super.onTouchEvent(event);
    }       
}

So now the tapping stops the number issue, but there are of course other worse side effects. So please don't take the above as a solution, it is simply to confirm my suspicion.

like image 154
Fracdroid Avatar answered Mar 03 '26 06:03

Fracdroid