FileDocCategorySizeDatePackage
NumberPicker.javaAPI DocAndroid 5.1 API103598Thu Mar 12 22:22:10 GMT 2015android.widget

NumberPicker

public class NumberPicker extends LinearLayout
A widget that enables the user to select a number from a predefined range. There are two flavors of this widget and which one is presented to the user depends on the current theme.
  • If the current theme is derived from {@link android.R.style#Theme} the widget presents the current value as an editable input field with an increment button above and a decrement button below. Long pressing the buttons allows for a quick change of the current value. Tapping on the input field allows to type in a desired value.
  • If the current theme is derived from {@link android.R.style#Theme_Holo} or {@link android.R.style#Theme_Holo_Light} the widget presents the current value as an editable input field with a lesser value above and a greater value below. Tapping on the lesser or greater value selects it by animating the number axis up or down to make the chosen value current. Flinging up or down allows for multiple increments or decrements of the current value. Long pressing on the lesser and greater values also allows for a quick change of the current value. Tapping on the current value allows to type in a desired value.

For an example of using this widget, see {@link android.widget.TimePicker}.

Fields Summary
private static final int
SELECTOR_WHEEL_ITEM_COUNT
The number of items show in the selector wheel.
private static final long
DEFAULT_LONG_PRESS_UPDATE_INTERVAL
The default update interval during long press.
private static final int
SELECTOR_MIDDLE_ITEM_INDEX
The index of the middle selector item.
private static final int
SELECTOR_MAX_FLING_VELOCITY_ADJUSTMENT
The coefficient by which to adjust (divide) the max fling velocity.
private static final int
SELECTOR_ADJUSTMENT_DURATION_MILLIS
The the duration for adjusting the selector wheel.
private static final int
SNAP_SCROLL_DURATION
The duration of scrolling while snapping to a given position.
private static final float
TOP_AND_BOTTOM_FADING_EDGE_STRENGTH
The strength of fading in the top and bottom while drawing the selector.
private static final int
UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT
The default unscaled height of the selection divider.
private static final int
UNSCALED_DEFAULT_SELECTION_DIVIDERS_DISTANCE
The default unscaled distance between the selection dividers.
private static final int
DEFAULT_LAYOUT_RESOURCE_ID
The resource id for the default layout.
private static final int
SIZE_UNSPECIFIED
Constant for unspecified size.
private static final TwoDigitFormatter
sTwoDigitFormatter
private final ImageButton
mIncrementButton
The increment button.
private final ImageButton
mDecrementButton
The decrement button.
private final EditText
mInputText
The text for showing the current value.
private final int
mSelectionDividersDistance
The distance between the two selection dividers.
private final int
mMinHeight
The min height of this widget.
private final int
mMaxHeight
The max height of this widget.
private final int
mMinWidth
The max width of this widget.
private int
mMaxWidth
The max width of this widget.
private final boolean
mComputeMaxWidth
Flag whether to compute the max width.
private final int
mTextSize
The height of the text.
private int
mSelectorTextGapHeight
The height of the gap between text elements if the selector wheel.
private String[]
mDisplayedValues
The values to be displayed instead the indices.
private int
mMinValue
Lower value of the range of numbers allowed for the NumberPicker
private int
mMaxValue
Upper value of the range of numbers allowed for the NumberPicker
private int
mValue
Current value of this NumberPicker
private OnValueChangeListener
mOnValueChangeListener
Listener to be notified upon current value change.
private OnScrollListener
mOnScrollListener
Listener to be notified upon scroll state change.
private Formatter
mFormatter
Formatter for for displaying the current value.
private long
mLongPressUpdateInterval
The speed for updating the value form long press.
private final android.util.SparseArray
mSelectorIndexToStringCache
Cache for the string representation of selector indices.
private final int[]
mSelectorIndices
The selector indices whose value are show by the selector.
private final android.graphics.Paint
mSelectorWheelPaint
The {@link Paint} for drawing the selector.
private final android.graphics.drawable.Drawable
mVirtualButtonPressedDrawable
The {@link Drawable} for pressed virtual (increment/decrement) buttons.
private int
mSelectorElementHeight
The height of a selector element (text + gap).
private int
mInitialScrollOffset
The initial offset of the scroll selector.
private int
mCurrentScrollOffset
The current offset of the scroll selector.
private final Scroller
mFlingScroller
The {@link Scroller} responsible for flinging the selector.
private final Scroller
mAdjustScroller
The {@link Scroller} responsible for adjusting the selector.
private int
mPreviousScrollerY
The previous Y coordinate while scrolling the selector.
private SetSelectionCommand
mSetSelectionCommand
Handle to the reusable command for setting the input text selection.
private ChangeCurrentByOneFromLongPressCommand
mChangeCurrentByOneFromLongPressCommand
Handle to the reusable command for changing the current value from long press by one.
private BeginSoftInputOnLongPressCommand
mBeginSoftInputOnLongPressCommand
Command for beginning an edit of the current value via IME on long press.
private float
mLastDownEventY
The Y position of the last down event.
private long
mLastDownEventTime
The time of the last down event.
private float
mLastDownOrMoveEventY
The Y position of the last down or move event.
private android.view.VelocityTracker
mVelocityTracker
Determines speed during touch scrolling.
private int
mTouchSlop
private int
mMinimumFlingVelocity
private int
mMaximumFlingVelocity
private boolean
mWrapSelectorWheel
Flag whether the selector should wrap around.
private final int
mSolidColor
The back ground color used to optimize scroller fading.
private final boolean
mHasSelectorWheel
Flag whether this widget has a selector wheel.
private final android.graphics.drawable.Drawable
mSelectionDivider
Divider for showing item to be selected while scrolling
private final int
mSelectionDividerHeight
The height of the selection divider.
private int
mScrollState
The current scroll state of the number picker.
private boolean
mIgnoreMoveEvents
Flag whether to ignore move events - we ignore such when we show in IME to prevent the content from scrolling.
private boolean
mPerformClickOnTap
Flag whether to perform a click on tap.
private int
mTopSelectionDividerTop
The top of the top selection divider.
private int
mBottomSelectionDividerBottom
The bottom of the bottom selection divider.
private int
mLastHoveredChildVirtualViewId
The virtual id of the last hovered child.
private boolean
mIncrementVirtualButtonPressed
Whether the increment virtual button is pressed.
private boolean
mDecrementVirtualButtonPressed
Whether the decrement virtual button is pressed.
private AccessibilityNodeProviderImpl
mAccessibilityNodeProvider
Provider to report to clients the semantic structure of this widget.
private final PressedStateHelper
mPressedStateHelper
Helper class for managing pressed state of the virtual buttons.
private int
mLastHandledDownDpadKeyCode
The keycode of the last handled DPAD down event.
private boolean
mHideWheelUntilFocused
If true then the selector wheel is hidden until the picker has focus.
private static final char[]
DIGIT_CHARACTERS
The numbers accepted by the input text's {@link Filter}
Constructors Summary
public NumberPicker(android.content.Context context)
Create a new number picker.

param
context The application environment.


                                                                                     
              
    

                    
       

                                    
           
    

                   
       
        this(context, null);
    
public NumberPicker(android.content.Context context, android.util.AttributeSet attrs)
Create a new number picker.

param
context The application environment.
param
attrs A collection of attributes.

        this(context, attrs, R.attr.numberPickerStyle);
    
public NumberPicker(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr)
Create a new number picker

param
context the application environment.
param
attrs a collection of attributes.
param
defStyleAttr An attribute in the current theme that contains a reference to a style resource that supplies default values for the view. Can be 0 to not look for defaults.

        this(context, attrs, defStyleAttr, 0);
    
public NumberPicker(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr, int defStyleRes)
Create a new number picker

param
context the application environment.
param
attrs a collection of attributes.
param
defStyleAttr An attribute in the current theme that contains a reference to a style resource that supplies default values for the view. Can be 0 to not look for defaults.
param
defStyleRes A resource identifier of a style resource that supplies default values for the view, used only if defStyleAttr is 0 or can not be found in the theme. Can be 0 to not look for defaults.

        super(context, attrs, defStyleAttr, defStyleRes);

        // process style attributes
        final TypedArray attributesArray = context.obtainStyledAttributes(
                attrs, R.styleable.NumberPicker, defStyleAttr, defStyleRes);
        final int layoutResId = attributesArray.getResourceId(
                R.styleable.NumberPicker_internalLayout, DEFAULT_LAYOUT_RESOURCE_ID);

        mHasSelectorWheel = (layoutResId != DEFAULT_LAYOUT_RESOURCE_ID);

        mHideWheelUntilFocused = attributesArray.getBoolean(
            R.styleable.NumberPicker_hideWheelUntilFocused, false);

        mSolidColor = attributesArray.getColor(R.styleable.NumberPicker_solidColor, 0);

        mSelectionDivider = attributesArray.getDrawable(R.styleable.NumberPicker_selectionDivider);

        final int defSelectionDividerHeight = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT,
                getResources().getDisplayMetrics());
        mSelectionDividerHeight = attributesArray.getDimensionPixelSize(
                R.styleable.NumberPicker_selectionDividerHeight, defSelectionDividerHeight);

        final int defSelectionDividerDistance = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_SELECTION_DIVIDERS_DISTANCE,
                getResources().getDisplayMetrics());
        mSelectionDividersDistance = attributesArray.getDimensionPixelSize(
                R.styleable.NumberPicker_selectionDividersDistance, defSelectionDividerDistance);

        mMinHeight = attributesArray.getDimensionPixelSize(
                R.styleable.NumberPicker_internalMinHeight, SIZE_UNSPECIFIED);

        mMaxHeight = attributesArray.getDimensionPixelSize(
                R.styleable.NumberPicker_internalMaxHeight, SIZE_UNSPECIFIED);
        if (mMinHeight != SIZE_UNSPECIFIED && mMaxHeight != SIZE_UNSPECIFIED
                && mMinHeight > mMaxHeight) {
            throw new IllegalArgumentException("minHeight > maxHeight");
        }

        mMinWidth = attributesArray.getDimensionPixelSize(
                R.styleable.NumberPicker_internalMinWidth, SIZE_UNSPECIFIED);

        mMaxWidth = attributesArray.getDimensionPixelSize(
                R.styleable.NumberPicker_internalMaxWidth, SIZE_UNSPECIFIED);
        if (mMinWidth != SIZE_UNSPECIFIED && mMaxWidth != SIZE_UNSPECIFIED
                && mMinWidth > mMaxWidth) {
            throw new IllegalArgumentException("minWidth > maxWidth");
        }

        mComputeMaxWidth = (mMaxWidth == SIZE_UNSPECIFIED);

        mVirtualButtonPressedDrawable = attributesArray.getDrawable(
                R.styleable.NumberPicker_virtualButtonPressedDrawable);

        attributesArray.recycle();

        mPressedStateHelper = new PressedStateHelper();

        // By default Linearlayout that we extend is not drawn. This is
        // its draw() method is not called but dispatchDraw() is called
        // directly (see ViewGroup.drawChild()). However, this class uses
        // the fading edge effect implemented by View and we need our
        // draw() method to be called. Therefore, we declare we will draw.
        setWillNotDraw(!mHasSelectorWheel);

        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(layoutResId, this, true);

        OnClickListener onClickListener = new OnClickListener() {
            public void onClick(View v) {
                hideSoftInput();
                mInputText.clearFocus();
                if (v.getId() == R.id.increment) {
                    changeValueByOne(true);
                } else {
                    changeValueByOne(false);
                }
            }
        };

        OnLongClickListener onLongClickListener = new OnLongClickListener() {
            public boolean onLongClick(View v) {
                hideSoftInput();
                mInputText.clearFocus();
                if (v.getId() == R.id.increment) {
                    postChangeCurrentByOneFromLongPress(true, 0);
                } else {
                    postChangeCurrentByOneFromLongPress(false, 0);
                }
                return true;
            }
        };

        // increment button
        if (!mHasSelectorWheel) {
            mIncrementButton = (ImageButton) findViewById(R.id.increment);
            mIncrementButton.setOnClickListener(onClickListener);
            mIncrementButton.setOnLongClickListener(onLongClickListener);
        } else {
            mIncrementButton = null;
        }

        // decrement button
        if (!mHasSelectorWheel) {
            mDecrementButton = (ImageButton) findViewById(R.id.decrement);
            mDecrementButton.setOnClickListener(onClickListener);
            mDecrementButton.setOnLongClickListener(onLongClickListener);
        } else {
            mDecrementButton = null;
        }

        // input text
        mInputText = (EditText) findViewById(R.id.numberpicker_input);
        mInputText.setOnFocusChangeListener(new OnFocusChangeListener() {
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus) {
                    mInputText.selectAll();
                } else {
                    mInputText.setSelection(0, 0);
                    validateInputTextView(v);
                }
            }
        });
        mInputText.setFilters(new InputFilter[] {
            new InputTextFilter()
        });

        mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
        mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);

        // initialize constants
        ViewConfiguration configuration = ViewConfiguration.get(context);
        mTouchSlop = configuration.getScaledTouchSlop();
        mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity();
        mMaximumFlingVelocity = configuration.getScaledMaximumFlingVelocity()
                / SELECTOR_MAX_FLING_VELOCITY_ADJUSTMENT;
        mTextSize = (int) mInputText.getTextSize();

        // create the selector wheel paint
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextAlign(Align.CENTER);
        paint.setTextSize(mTextSize);
        paint.setTypeface(mInputText.getTypeface());
        ColorStateList colors = mInputText.getTextColors();
        int color = colors.getColorForState(ENABLED_STATE_SET, Color.WHITE);
        paint.setColor(color);
        mSelectorWheelPaint = paint;

        // create the fling and adjust scrollers
        mFlingScroller = new Scroller(getContext(), null, true);
        mAdjustScroller = new Scroller(getContext(), new DecelerateInterpolator(2.5f));

        updateInputTextView();

        // If not explicitly specified this view is important for accessibility.
        if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
            setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
        }
    
Methods Summary
private voidchangeValueByOne(boolean increment)
Changes the current value by one which is increment or decrement based on the passes argument. decrement the current value.

param
increment True to increment, false to decrement.

        if (mHasSelectorWheel) {
            mInputText.setVisibility(View.INVISIBLE);
            if (!moveToFinalScrollerPosition(mFlingScroller)) {
                moveToFinalScrollerPosition(mAdjustScroller);
            }
            mPreviousScrollerY = 0;
            if (increment) {
                mFlingScroller.startScroll(0, 0, 0, -mSelectorElementHeight, SNAP_SCROLL_DURATION);
            } else {
                mFlingScroller.startScroll(0, 0, 0, mSelectorElementHeight, SNAP_SCROLL_DURATION);
            }
            invalidate();
        } else {
            if (increment) {
                setValueInternal(mValue + 1, true);
            } else {
                setValueInternal(mValue - 1, true);
            }
        }
    
public voidcomputeScroll()

        Scroller scroller = mFlingScroller;
        if (scroller.isFinished()) {
            scroller = mAdjustScroller;
            if (scroller.isFinished()) {
                return;
            }
        }
        scroller.computeScrollOffset();
        int currentScrollerY = scroller.getCurrY();
        if (mPreviousScrollerY == 0) {
            mPreviousScrollerY = scroller.getStartY();
        }
        scrollBy(0, currentScrollerY - mPreviousScrollerY);
        mPreviousScrollerY = currentScrollerY;
        if (scroller.isFinished()) {
            onScrollerFinished(scroller);
        } else {
            invalidate();
        }
    
protected intcomputeVerticalScrollExtent()

        return getHeight();
    
protected intcomputeVerticalScrollOffset()

        return mCurrentScrollOffset;
    
protected intcomputeVerticalScrollRange()

        return (mMaxValue - mMinValue + 1) * mSelectorElementHeight;
    
private voiddecrementSelectorIndices(int[] selectorIndices)
Decrements the selectorIndices whose string representations will be displayed in the selector.

        for (int i = selectorIndices.length - 1; i > 0; i--) {
            selectorIndices[i] = selectorIndices[i - 1];
        }
        int nextScrollSelectorIndex = selectorIndices[1] - 1;
        if (mWrapSelectorWheel && nextScrollSelectorIndex < mMinValue) {
            nextScrollSelectorIndex = mMaxValue;
        }
        selectorIndices[0] = nextScrollSelectorIndex;
        ensureCachedScrollSelectorValue(nextScrollSelectorIndex);
    
protected booleandispatchHoverEvent(android.view.MotionEvent event)

        if (!mHasSelectorWheel) {
            return super.dispatchHoverEvent(event);
        }
        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
            final int eventY = (int) event.getY();
            final int hoveredVirtualViewId;
            if (eventY < mTopSelectionDividerTop) {
                hoveredVirtualViewId = AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_DECREMENT;
            } else if (eventY > mBottomSelectionDividerBottom) {
                hoveredVirtualViewId = AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_INCREMENT;
            } else {
                hoveredVirtualViewId = AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_INPUT;
            }
            final int action = event.getActionMasked();
            AccessibilityNodeProviderImpl provider =
                (AccessibilityNodeProviderImpl) getAccessibilityNodeProvider();
            switch (action) {
                case MotionEvent.ACTION_HOVER_ENTER: {
                    provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId,
                            AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
                    mLastHoveredChildVirtualViewId = hoveredVirtualViewId;
                    provider.performAction(hoveredVirtualViewId,
                            AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
                } break;
                case MotionEvent.ACTION_HOVER_MOVE: {
                    if (mLastHoveredChildVirtualViewId != hoveredVirtualViewId
                            && mLastHoveredChildVirtualViewId != View.NO_ID) {
                        provider.sendAccessibilityEventForVirtualView(
                                mLastHoveredChildVirtualViewId,
                                AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
                        provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId,
                                AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
                        mLastHoveredChildVirtualViewId = hoveredVirtualViewId;
                        provider.performAction(hoveredVirtualViewId,
                                AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
                    }
                } break;
                case MotionEvent.ACTION_HOVER_EXIT: {
                    provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId,
                            AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
                    mLastHoveredChildVirtualViewId = View.NO_ID;
                } break;
            }
        }
        return false;
    
public booleandispatchKeyEvent(android.view.KeyEvent event)

        final int keyCode = event.getKeyCode();
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
            case KeyEvent.KEYCODE_ENTER:
                removeAllCallbacks();
                break;
            case KeyEvent.KEYCODE_DPAD_DOWN:
            case KeyEvent.KEYCODE_DPAD_UP:
                if (!mHasSelectorWheel) {
                    break;
                }
                switch (event.getAction()) {
                    case KeyEvent.ACTION_DOWN:
                        if (mWrapSelectorWheel || ((keyCode == KeyEvent.KEYCODE_DPAD_DOWN)
                                ? getValue() < getMaxValue() : getValue() > getMinValue())) {
                            requestFocus();
                            mLastHandledDownDpadKeyCode = keyCode;
                            removeAllCallbacks();
                            if (mFlingScroller.isFinished()) {
                                changeValueByOne(keyCode == KeyEvent.KEYCODE_DPAD_DOWN);
                            }
                            return true;
                        }
                        break;
                    case KeyEvent.ACTION_UP:
                        if (mLastHandledDownDpadKeyCode == keyCode) {
                            mLastHandledDownDpadKeyCode = -1;
                            return true;
                        }
                        break;
                }
        }
        return super.dispatchKeyEvent(event);
    
public booleandispatchTouchEvent(android.view.MotionEvent event)

        final int action = event.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                removeAllCallbacks();
                break;
        }
        return super.dispatchTouchEvent(event);
    
public booleandispatchTrackballEvent(android.view.MotionEvent event)

        final int action = event.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                removeAllCallbacks();
                break;
        }
        return super.dispatchTrackballEvent(event);
    
private voidensureCachedScrollSelectorValue(int selectorIndex)
Ensures we have a cached string representation of the given selectorIndex to avoid multiple instantiations of the same string.

        SparseArray<String> cache = mSelectorIndexToStringCache;
        String scrollSelectorValue = cache.get(selectorIndex);
        if (scrollSelectorValue != null) {
            return;
        }
        if (selectorIndex < mMinValue || selectorIndex > mMaxValue) {
            scrollSelectorValue = "";
        } else {
            if (mDisplayedValues != null) {
                int displayedValueIndex = selectorIndex - mMinValue;
                scrollSelectorValue = mDisplayedValues[displayedValueIndex];
            } else {
                scrollSelectorValue = formatNumber(selectorIndex);
            }
        }
        cache.put(selectorIndex, scrollSelectorValue);
    
private booleanensureScrollWheelAdjusted()
Ensures that the scroll wheel is adjusted i.e. there is no offset and the middle element is in the middle of the widget.

return
Whether an adjustment has been made.

        // adjust to the closest value
        int deltaY = mInitialScrollOffset - mCurrentScrollOffset;
        if (deltaY != 0) {
            mPreviousScrollerY = 0;
            if (Math.abs(deltaY) > mSelectorElementHeight / 2) {
                deltaY += (deltaY > 0) ? -mSelectorElementHeight : mSelectorElementHeight;
            }
            mAdjustScroller.startScroll(0, 0, 0, deltaY, SELECTOR_ADJUSTMENT_DURATION_MILLIS);
            invalidate();
            return true;
        }
        return false;
    
private voidfling(int velocityY)
Flings the selector with the given velocityY.

        mPreviousScrollerY = 0;

        if (velocityY > 0) {
            mFlingScroller.fling(0, 0, 0, velocityY, 0, 0, 0, Integer.MAX_VALUE);
        } else {
            mFlingScroller.fling(0, Integer.MAX_VALUE, 0, velocityY, 0, 0, 0, Integer.MAX_VALUE);
        }

        invalidate();
    
private java.lang.StringformatNumber(int value)

        return (mFormatter != null) ? mFormatter.format(value) : formatNumberWithLocale(value);
    
private static java.lang.StringformatNumberWithLocale(int value)

        return String.format(Locale.getDefault(), "%d", value);
    
public android.view.accessibility.AccessibilityNodeProvidergetAccessibilityNodeProvider()

        if (!mHasSelectorWheel) {
            return super.getAccessibilityNodeProvider();
        }
        if (mAccessibilityNodeProvider == null) {
            mAccessibilityNodeProvider = new AccessibilityNodeProviderImpl();
        }
        return mAccessibilityNodeProvider;
    
protected floatgetBottomFadingEdgeStrength()

        return TOP_AND_BOTTOM_FADING_EDGE_STRENGTH;
    
public java.lang.String[]getDisplayedValues()
Gets the values to be displayed instead of string values.

return
The displayed values.

        return mDisplayedValues;
    
public intgetMaxValue()
Returns the max value of the picker.

return
The max value.

        return mMaxValue;
    
public intgetMinValue()
Returns the min value of the picker.

return
The min value

        return mMinValue;
    
private intgetSelectedPos(java.lang.String value)

return
The selected index given its displayed value.

        if (mDisplayedValues == null) {
            try {
                return Integer.parseInt(value);
            } catch (NumberFormatException e) {
                // Ignore as if it's not a number we don't care
            }
        } else {
            for (int i = 0; i < mDisplayedValues.length; i++) {
                // Don't force the user to type in jan when ja will do
                value = value.toLowerCase();
                if (mDisplayedValues[i].toLowerCase().startsWith(value)) {
                    return mMinValue + i;
                }
            }

            /*
             * The user might have typed in a number into the month field i.e.
             * 10 instead of OCT so support that too.
             */
            try {
                return Integer.parseInt(value);
            } catch (NumberFormatException e) {

                // Ignore as if it's not a number we don't care
            }
        }
        return mMinValue;
    
public intgetSolidColor()

        return mSolidColor;
    
protected floatgetTopFadingEdgeStrength()

        return TOP_AND_BOTTOM_FADING_EDGE_STRENGTH;
    
public static final android.widget.NumberPicker$FormattergetTwoDigitFormatter()

hide


          
         
        return sTwoDigitFormatter;
    
public intgetValue()
Returns the value of the picker.

return
The value.

        return mValue;
    
public booleangetWrapSelectorWheel()
Gets whether the selector wheel wraps when reaching the min/max value.

return
True if the selector wheel wraps.
see
#getMinValue()
see
#getMaxValue()

        return mWrapSelectorWheel;
    
private intgetWrappedSelectorIndex(int selectorIndex)

return
The wrapped index selectorIndex value.

        if (selectorIndex > mMaxValue) {
            return mMinValue + (selectorIndex - mMaxValue) % (mMaxValue - mMinValue) - 1;
        } else if (selectorIndex < mMinValue) {
            return mMaxValue - (mMinValue - selectorIndex) % (mMaxValue - mMinValue) + 1;
        }
        return selectorIndex;
    
private voidhideSoftInput()
Hides the soft input if it is active for the input text.

        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
        if (inputMethodManager != null && inputMethodManager.isActive(mInputText)) {
            inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
            if (mHasSelectorWheel) {
                mInputText.setVisibility(View.INVISIBLE);
            }
        }
    
private voidincrementSelectorIndices(int[] selectorIndices)
Increments the selectorIndices whose string representations will be displayed in the selector.

        for (int i = 0; i < selectorIndices.length - 1; i++) {
            selectorIndices[i] = selectorIndices[i + 1];
        }
        int nextScrollSelectorIndex = selectorIndices[selectorIndices.length - 2] + 1;
        if (mWrapSelectorWheel && nextScrollSelectorIndex > mMaxValue) {
            nextScrollSelectorIndex = mMinValue;
        }
        selectorIndices[selectorIndices.length - 1] = nextScrollSelectorIndex;
        ensureCachedScrollSelectorValue(nextScrollSelectorIndex);
    
private voidinitializeFadingEdges()

        setVerticalFadingEdgeEnabled(true);
        setFadingEdgeLength((mBottom - mTop - mTextSize) / 2);
    
private voidinitializeSelectorWheel()

        initializeSelectorWheelIndices();
        int[] selectorIndices = mSelectorIndices;
        int totalTextHeight = selectorIndices.length * mTextSize;
        float totalTextGapHeight = (mBottom - mTop) - totalTextHeight;
        float textGapCount = selectorIndices.length;
        mSelectorTextGapHeight = (int) (totalTextGapHeight / textGapCount + 0.5f);
        mSelectorElementHeight = mTextSize + mSelectorTextGapHeight;
        // Ensure that the middle item is positioned the same as the text in
        // mInputText
        int editTextTextPosition = mInputText.getBaseline() + mInputText.getTop();
        mInitialScrollOffset = editTextTextPosition
                - (mSelectorElementHeight * SELECTOR_MIDDLE_ITEM_INDEX);
        mCurrentScrollOffset = mInitialScrollOffset;
        updateInputTextView();
    
private voidinitializeSelectorWheelIndices()
Resets the selector indices and clear the cached string representation of these indices.

        mSelectorIndexToStringCache.clear();
        int[] selectorIndices = mSelectorIndices;
        int current = getValue();
        for (int i = 0; i < mSelectorIndices.length; i++) {
            int selectorIndex = current + (i - SELECTOR_MIDDLE_ITEM_INDEX);
            if (mWrapSelectorWheel) {
                selectorIndex = getWrappedSelectorIndex(selectorIndex);
            }
            selectorIndices[i] = selectorIndex;
            ensureCachedScrollSelectorValue(selectorIndices[i]);
        }
    
private intmakeMeasureSpec(int measureSpec, int maxSize)
Makes a measure spec that tries greedily to use the max value.

param
measureSpec The measure spec.
param
maxSize The max value for the size.
return
A measure spec greedily imposing the max size.

        if (maxSize == SIZE_UNSPECIFIED) {
            return measureSpec;
        }
        final int size = MeasureSpec.getSize(measureSpec);
        final int mode = MeasureSpec.getMode(measureSpec);
        switch (mode) {
            case MeasureSpec.EXACTLY:
                return measureSpec;
            case MeasureSpec.AT_MOST:
                return MeasureSpec.makeMeasureSpec(Math.min(size, maxSize), MeasureSpec.EXACTLY);
            case MeasureSpec.UNSPECIFIED:
                return MeasureSpec.makeMeasureSpec(maxSize, MeasureSpec.EXACTLY);
            default:
                throw new IllegalArgumentException("Unknown measure mode: " + mode);
        }
    
private booleanmoveToFinalScrollerPosition(Scroller scroller)
Move to the final position of a scroller. Ensures to force finish the scroller and if it is not at its final position a scroll of the selector wheel is performed to fast forward to the final position.

param
scroller The scroller to whose final position to get.
return
True of the a move was performed, i.e. the scroller was not in final position.

        scroller.forceFinished(true);
        int amountToScroll = scroller.getFinalY() - scroller.getCurrY();
        int futureScrollOffset = (mCurrentScrollOffset + amountToScroll) % mSelectorElementHeight;
        int overshootAdjustment = mInitialScrollOffset - futureScrollOffset;
        if (overshootAdjustment != 0) {
            if (Math.abs(overshootAdjustment) > mSelectorElementHeight / 2) {
                if (overshootAdjustment > 0) {
                    overshootAdjustment -= mSelectorElementHeight;
                } else {
                    overshootAdjustment += mSelectorElementHeight;
                }
            }
            amountToScroll += overshootAdjustment;
            scrollBy(0, amountToScroll);
            return true;
        }
        return false;
    
private voidnotifyChange(int previous, int current)
Notifies the listener, if registered, of a change of the value of this NumberPicker.

        if (mOnValueChangeListener != null) {
            mOnValueChangeListener.onValueChange(this, previous, mValue);
        }
    
protected voidonDetachedFromWindow()

        super.onDetachedFromWindow();
        removeAllCallbacks();
    
protected voidonDraw(android.graphics.Canvas canvas)

        if (!mHasSelectorWheel) {
            super.onDraw(canvas);
            return;
        }
        final boolean showSelectorWheel = mHideWheelUntilFocused ? hasFocus() : true;
        float x = (mRight - mLeft) / 2;
        float y = mCurrentScrollOffset;

        // draw the virtual buttons pressed state if needed
        if (showSelectorWheel && mVirtualButtonPressedDrawable != null
                && mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
            if (mDecrementVirtualButtonPressed) {
                mVirtualButtonPressedDrawable.setState(PRESSED_STATE_SET);
                mVirtualButtonPressedDrawable.setBounds(0, 0, mRight, mTopSelectionDividerTop);
                mVirtualButtonPressedDrawable.draw(canvas);
            }
            if (mIncrementVirtualButtonPressed) {
                mVirtualButtonPressedDrawable.setState(PRESSED_STATE_SET);
                mVirtualButtonPressedDrawable.setBounds(0, mBottomSelectionDividerBottom, mRight,
                        mBottom);
                mVirtualButtonPressedDrawable.draw(canvas);
            }
        }

        // draw the selector wheel
        int[] selectorIndices = mSelectorIndices;
        for (int i = 0; i < selectorIndices.length; i++) {
            int selectorIndex = selectorIndices[i];
            String scrollSelectorValue = mSelectorIndexToStringCache.get(selectorIndex);
            // Do not draw the middle item if input is visible since the input
            // is shown only if the wheel is static and it covers the middle
            // item. Otherwise, if the user starts editing the text via the
            // IME he may see a dimmed version of the old value intermixed
            // with the new one.
            if ((showSelectorWheel && i != SELECTOR_MIDDLE_ITEM_INDEX) ||
                (i == SELECTOR_MIDDLE_ITEM_INDEX && mInputText.getVisibility() != VISIBLE)) {
                canvas.drawText(scrollSelectorValue, x, y, mSelectorWheelPaint);
            }
            y += mSelectorElementHeight;
        }

        // draw the selection dividers
        if (showSelectorWheel && mSelectionDivider != null) {
            // draw the top divider
            int topOfTopDivider = mTopSelectionDividerTop;
            int bottomOfTopDivider = topOfTopDivider + mSelectionDividerHeight;
            mSelectionDivider.setBounds(0, topOfTopDivider, mRight, bottomOfTopDivider);
            mSelectionDivider.draw(canvas);

            // draw the bottom divider
            int bottomOfBottomDivider = mBottomSelectionDividerBottom;
            int topOfBottomDivider = bottomOfBottomDivider - mSelectionDividerHeight;
            mSelectionDivider.setBounds(0, topOfBottomDivider, mRight, bottomOfBottomDivider);
            mSelectionDivider.draw(canvas);
        }
    
public voidonInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent event)

        super.onInitializeAccessibilityEvent(event);
        event.setClassName(NumberPicker.class.getName());
        event.setScrollable(true);
        event.setScrollY((mMinValue + mValue) * mSelectorElementHeight);
        event.setMaxScrollY((mMaxValue - mMinValue) * mSelectorElementHeight);
    
public booleanonInterceptTouchEvent(android.view.MotionEvent event)

        if (!mHasSelectorWheel || !isEnabled()) {
            return false;
        }
        final int action = event.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN: {
                removeAllCallbacks();
                mInputText.setVisibility(View.INVISIBLE);
                mLastDownOrMoveEventY = mLastDownEventY = event.getY();
                mLastDownEventTime = event.getEventTime();
                mIgnoreMoveEvents = false;
                mPerformClickOnTap = false;
                // Handle pressed state before any state change.
                if (mLastDownEventY < mTopSelectionDividerTop) {
                    if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
                        mPressedStateHelper.buttonPressDelayed(
                                PressedStateHelper.BUTTON_DECREMENT);
                    }
                } else if (mLastDownEventY > mBottomSelectionDividerBottom) {
                    if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
                        mPressedStateHelper.buttonPressDelayed(
                                PressedStateHelper.BUTTON_INCREMENT);
                    }
                }
                // Make sure we support flinging inside scrollables.
                getParent().requestDisallowInterceptTouchEvent(true);
                if (!mFlingScroller.isFinished()) {
                    mFlingScroller.forceFinished(true);
                    mAdjustScroller.forceFinished(true);
                    onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                } else if (!mAdjustScroller.isFinished()) {
                    mFlingScroller.forceFinished(true);
                    mAdjustScroller.forceFinished(true);
                } else if (mLastDownEventY < mTopSelectionDividerTop) {
                    hideSoftInput();
                    postChangeCurrentByOneFromLongPress(
                            false, ViewConfiguration.getLongPressTimeout());
                } else if (mLastDownEventY > mBottomSelectionDividerBottom) {
                    hideSoftInput();
                    postChangeCurrentByOneFromLongPress(
                            true, ViewConfiguration.getLongPressTimeout());
                } else {
                    mPerformClickOnTap = true;
                    postBeginSoftInputOnLongPressCommand();
                }
                return true;
            }
        }
        return false;
    
protected voidonLayout(boolean changed, int left, int top, int right, int bottom)

        if (!mHasSelectorWheel) {
            super.onLayout(changed, left, top, right, bottom);
            return;
        }
        final int msrdWdth = getMeasuredWidth();
        final int msrdHght = getMeasuredHeight();

        // Input text centered horizontally.
        final int inptTxtMsrdWdth = mInputText.getMeasuredWidth();
        final int inptTxtMsrdHght = mInputText.getMeasuredHeight();
        final int inptTxtLeft = (msrdWdth - inptTxtMsrdWdth) / 2;
        final int inptTxtTop = (msrdHght - inptTxtMsrdHght) / 2;
        final int inptTxtRight = inptTxtLeft + inptTxtMsrdWdth;
        final int inptTxtBottom = inptTxtTop + inptTxtMsrdHght;
        mInputText.layout(inptTxtLeft, inptTxtTop, inptTxtRight, inptTxtBottom);

        if (changed) {
            // need to do all this when we know our size
            initializeSelectorWheel();
            initializeFadingEdges();
            mTopSelectionDividerTop = (getHeight() - mSelectionDividersDistance) / 2
                    - mSelectionDividerHeight;
            mBottomSelectionDividerBottom = mTopSelectionDividerTop + 2 * mSelectionDividerHeight
                    + mSelectionDividersDistance;
        }
    
protected voidonMeasure(int widthMeasureSpec, int heightMeasureSpec)

        if (!mHasSelectorWheel) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }
        // Try greedily to fit the max width and height.
        final int newWidthMeasureSpec = makeMeasureSpec(widthMeasureSpec, mMaxWidth);
        final int newHeightMeasureSpec = makeMeasureSpec(heightMeasureSpec, mMaxHeight);
        super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec);
        // Flag if we are measured with width or height less than the respective min.
        final int widthSize = resolveSizeAndStateRespectingMinSize(mMinWidth, getMeasuredWidth(),
                widthMeasureSpec);
        final int heightSize = resolveSizeAndStateRespectingMinSize(mMinHeight, getMeasuredHeight(),
                heightMeasureSpec);
        setMeasuredDimension(widthSize, heightSize);
    
private voidonScrollStateChange(int scrollState)
Handles transition to a given scrollState

        if (mScrollState == scrollState) {
            return;
        }
        mScrollState = scrollState;
        if (mOnScrollListener != null) {
            mOnScrollListener.onScrollStateChange(this, scrollState);
        }
    
private voidonScrollerFinished(Scroller scroller)
Callback invoked upon completion of a given scroller.

        if (scroller == mFlingScroller) {
            if (!ensureScrollWheelAdjusted()) {
                updateInputTextView();
            }
            onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
        } else {
            if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                updateInputTextView();
            }
        }
    
public booleanonTouchEvent(android.view.MotionEvent event)

        if (!isEnabled() || !mHasSelectorWheel) {
            return false;
        }
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
        int action = event.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_MOVE: {
                if (mIgnoreMoveEvents) {
                    break;
                }
                float currentMoveY = event.getY();
                if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                    int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
                    if (deltaDownY > mTouchSlop) {
                        removeAllCallbacks();
                        onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                    }
                } else {
                    int deltaMoveY = (int) ((currentMoveY - mLastDownOrMoveEventY));
                    scrollBy(0, deltaMoveY);
                    invalidate();
                }
                mLastDownOrMoveEventY = currentMoveY;
            } break;
            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 (mPerformClickOnTap) {
                            mPerformClickOnTap = false;
                            performClick();
                        } else {
                            int selectorIndexOffset = (eventY / mSelectorElementHeight)
                                    - SELECTOR_MIDDLE_ITEM_INDEX;
                            if (selectorIndexOffset > 0) {
                                changeValueByOne(true);
                                mPressedStateHelper.buttonTapped(
                                        PressedStateHelper.BUTTON_INCREMENT);
                            } else if (selectorIndexOffset < 0) {
                                changeValueByOne(false);
                                mPressedStateHelper.buttonTapped(
                                        PressedStateHelper.BUTTON_DECREMENT);
                            }
                        }
                    } else {
                        ensureScrollWheelAdjusted();
                    }
                    onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                }
                mVelocityTracker.recycle();
                mVelocityTracker = null;
            } break;
        }
        return true;
    
public booleanperformClick()

        if (!mHasSelectorWheel) {
            return super.performClick();
        } else if (!super.performClick()) {
            showSoftInput();
        }
        return true;
    
public booleanperformLongClick()

        if (!mHasSelectorWheel) {
            return super.performLongClick();
        } else if (!super.performLongClick()) {
            showSoftInput();
            mIgnoreMoveEvents = true;
        }
        return true;
    
private voidpostBeginSoftInputOnLongPressCommand()
Posts a command for beginning an edit of the current value via IME on long press.

        if (mBeginSoftInputOnLongPressCommand == null) {
            mBeginSoftInputOnLongPressCommand = new BeginSoftInputOnLongPressCommand();
        } else {
            removeCallbacks(mBeginSoftInputOnLongPressCommand);
        }
        postDelayed(mBeginSoftInputOnLongPressCommand, ViewConfiguration.getLongPressTimeout());
    
private voidpostChangeCurrentByOneFromLongPress(boolean increment, long delayMillis)
Posts a command for changing the current value by one.

param
increment Whether to increment or decrement the value.

        if (mChangeCurrentByOneFromLongPressCommand == null) {
            mChangeCurrentByOneFromLongPressCommand = new ChangeCurrentByOneFromLongPressCommand();
        } else {
            removeCallbacks(mChangeCurrentByOneFromLongPressCommand);
        }
        mChangeCurrentByOneFromLongPressCommand.setStep(increment);
        postDelayed(mChangeCurrentByOneFromLongPressCommand, delayMillis);
    
private voidpostSetSelectionCommand(int selectionStart, int selectionEnd)
Posts an {@link SetSelectionCommand} from the given selectionStart to selectionEnd.

        if (mSetSelectionCommand == null) {
            mSetSelectionCommand = new SetSelectionCommand();
        } else {
            removeCallbacks(mSetSelectionCommand);
        }
        mSetSelectionCommand.mSelectionStart = selectionStart;
        mSetSelectionCommand.mSelectionEnd = selectionEnd;
        post(mSetSelectionCommand);
    
private voidremoveAllCallbacks()
Removes all pending callback from the message queue.

        if (mChangeCurrentByOneFromLongPressCommand != null) {
            removeCallbacks(mChangeCurrentByOneFromLongPressCommand);
        }
        if (mSetSelectionCommand != null) {
            removeCallbacks(mSetSelectionCommand);
        }
        if (mBeginSoftInputOnLongPressCommand != null) {
            removeCallbacks(mBeginSoftInputOnLongPressCommand);
        }
        mPressedStateHelper.cancel();
    
private voidremoveBeginSoftInputCommand()
Removes the command for beginning an edit of the current value via IME.

        if (mBeginSoftInputOnLongPressCommand != null) {
            removeCallbacks(mBeginSoftInputOnLongPressCommand);
        }
    
private voidremoveChangeCurrentByOneFromLongPress()
Removes the command for changing the current value by one.

        if (mChangeCurrentByOneFromLongPressCommand != null) {
            removeCallbacks(mChangeCurrentByOneFromLongPressCommand);
        }
    
private intresolveSizeAndStateRespectingMinSize(int minSize, int measuredSize, int measureSpec)
Utility to reconcile a desired size and state, with constraints imposed by a MeasureSpec. Tries to respect the min size, unless a different size is imposed by the constraints.

param
minSize The minimal desired size.
param
measuredSize The currently measured size.
param
measureSpec The current measure spec.
return
The resolved size and state.

        if (minSize != SIZE_UNSPECIFIED) {
            final int desiredWidth = Math.max(minSize, measuredSize);
            return resolveSizeAndState(desiredWidth, measureSpec, 0);
        } else {
            return measuredSize;
        }
    
public voidscrollBy(int x, int y)

        int[] selectorIndices = mSelectorIndices;
        if (!mWrapSelectorWheel && y > 0
                && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
            mCurrentScrollOffset = mInitialScrollOffset;
            return;
        }
        if (!mWrapSelectorWheel && y < 0
                && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] >= mMaxValue) {
            mCurrentScrollOffset = mInitialScrollOffset;
            return;
        }
        mCurrentScrollOffset += y;
        while (mCurrentScrollOffset - mInitialScrollOffset > mSelectorTextGapHeight) {
            mCurrentScrollOffset -= mSelectorElementHeight;
            decrementSelectorIndices(selectorIndices);
            setValueInternal(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX], true);
            if (!mWrapSelectorWheel && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
                mCurrentScrollOffset = mInitialScrollOffset;
            }
        }
        while (mCurrentScrollOffset - mInitialScrollOffset < -mSelectorTextGapHeight) {
            mCurrentScrollOffset += mSelectorElementHeight;
            incrementSelectorIndices(selectorIndices);
            setValueInternal(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX], true);
            if (!mWrapSelectorWheel && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] >= mMaxValue) {
                mCurrentScrollOffset = mInitialScrollOffset;
            }
        }
    
public voidsetDisplayedValues(java.lang.String[] displayedValues)
Sets the values to be displayed.

param
displayedValues The displayed values. Note: The length of the displayed values array must be equal to the range of selectable numbers which is equal to {@link #getMaxValue()} - {@link #getMinValue()} + 1.

        if (mDisplayedValues == displayedValues) {
            return;
        }
        mDisplayedValues = displayedValues;
        if (mDisplayedValues != null) {
            // Allow text entry rather than strictly numeric entry.
            mInputText.setRawInputType(InputType.TYPE_CLASS_TEXT
                    | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
        } else {
            mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
        }
        updateInputTextView();
        initializeSelectorWheelIndices();
        tryComputeMaxWidth();
    
public voidsetEnabled(boolean enabled)

        super.setEnabled(enabled);
        if (!mHasSelectorWheel) {
            mIncrementButton.setEnabled(enabled);
        }
        if (!mHasSelectorWheel) {
            mDecrementButton.setEnabled(enabled);
        }
        mInputText.setEnabled(enabled);
    
public voidsetFormatter(android.widget.NumberPicker$Formatter formatter)
Set the formatter to be used for formatting the current value.

Note: If you have provided alternative values for the values this formatter is never invoked.

param
formatter The formatter object. If formatter is null, {@link String#valueOf(int)} will be used.
see
#setDisplayedValues(String[])

        if (formatter == mFormatter) {
            return;
        }
        mFormatter = formatter;
        initializeSelectorWheelIndices();
        updateInputTextView();
    
public voidsetMaxValue(int maxValue)
Sets the max value of the picker.

param
maxValue The max value inclusive. Note: The length of the displayed values array set via {@link #setDisplayedValues(String[])} must be equal to the range of selectable numbers which is equal to {@link #getMaxValue()} - {@link #getMinValue()} + 1.

        if (mMaxValue == maxValue) {
            return;
        }
        if (maxValue < 0) {
            throw new IllegalArgumentException("maxValue must be >= 0");
        }
        mMaxValue = maxValue;
        if (mMaxValue < mValue) {
            mValue = mMaxValue;
        }
        boolean wrapSelectorWheel = mMaxValue - mMinValue > mSelectorIndices.length;
        setWrapSelectorWheel(wrapSelectorWheel);
        initializeSelectorWheelIndices();
        updateInputTextView();
        tryComputeMaxWidth();
        invalidate();
    
public voidsetMinValue(int minValue)
Sets the min value of the picker.

param
minValue The min value inclusive. Note: The length of the displayed values array set via {@link #setDisplayedValues(String[])} must be equal to the range of selectable numbers which is equal to {@link #getMaxValue()} - {@link #getMinValue()} + 1.

        if (mMinValue == minValue) {
            return;
        }
        if (minValue < 0) {
            throw new IllegalArgumentException("minValue must be >= 0");
        }
        mMinValue = minValue;
        if (mMinValue > mValue) {
            mValue = mMinValue;
        }
        boolean wrapSelectorWheel = mMaxValue - mMinValue > mSelectorIndices.length;
        setWrapSelectorWheel(wrapSelectorWheel);
        initializeSelectorWheelIndices();
        updateInputTextView();
        tryComputeMaxWidth();
        invalidate();
    
public voidsetOnLongPressUpdateInterval(long intervalMillis)
Sets the speed at which the numbers be incremented and decremented when the up and down buttons are long pressed respectively.

The default value is 300 ms.

param
intervalMillis The speed (in milliseconds) at which the numbers will be incremented and decremented.

        mLongPressUpdateInterval = intervalMillis;
    
public voidsetOnScrollListener(android.widget.NumberPicker$OnScrollListener onScrollListener)
Set listener to be notified for scroll state changes.

param
onScrollListener The listener.

        mOnScrollListener = onScrollListener;
    
public voidsetOnValueChangedListener(android.widget.NumberPicker$OnValueChangeListener onValueChangedListener)
Sets the listener to be notified on change of the current value.

param
onValueChangedListener The listener.

        mOnValueChangeListener = onValueChangedListener;
    
public voidsetValue(int value)
Set the current value for the number picker.

If the argument is less than the {@link NumberPicker#getMinValue()} and {@link NumberPicker#getWrapSelectorWheel()} is false the current value is set to the {@link NumberPicker#getMinValue()} value.

If the argument is less than the {@link NumberPicker#getMinValue()} and {@link NumberPicker#getWrapSelectorWheel()} is true the current value is set to the {@link NumberPicker#getMaxValue()} value.

If the argument is less than the {@link NumberPicker#getMaxValue()} and {@link NumberPicker#getWrapSelectorWheel()} is false the current value is set to the {@link NumberPicker#getMaxValue()} value.

If the argument is less than the {@link NumberPicker#getMaxValue()} and {@link NumberPicker#getWrapSelectorWheel()} is true the current value is set to the {@link NumberPicker#getMinValue()} value.

param
value The current value.
see
#setWrapSelectorWheel(boolean)
see
#setMinValue(int)
see
#setMaxValue(int)

        setValueInternal(value, false);
    
private voidsetValueInternal(int current, boolean notifyChange)
Sets the current value of this NumberPicker.

param
current The new value of the NumberPicker.
param
notifyChange Whether to notify if the current value changed.

        if (mValue == current) {
            return;
        }
        // Wrap around the values if we go past the start or end
        if (mWrapSelectorWheel) {
            current = getWrappedSelectorIndex(current);
        } else {
            current = Math.max(current, mMinValue);
            current = Math.min(current, mMaxValue);
        }
        int previous = mValue;
        mValue = current;
        updateInputTextView();
        if (notifyChange) {
            notifyChange(previous, current);
        }
        initializeSelectorWheelIndices();
        invalidate();
    
public voidsetWrapSelectorWheel(boolean wrapSelectorWheel)
Sets whether the selector wheel shown during flinging/scrolling should wrap around the {@link NumberPicker#getMinValue()} and {@link NumberPicker#getMaxValue()} values.

By default if the range (max - min) is more than the number of items shown on the selector wheel the selector wheel wrapping is enabled.

Note: If the number of items, i.e. the range ( {@link #getMaxValue()} - {@link #getMinValue()}) is less than the number of items shown on the selector wheel, the selector wheel will not wrap. Hence, in such a case calling this method is a NOP.

param
wrapSelectorWheel Whether to wrap.

        final boolean wrappingAllowed = (mMaxValue - mMinValue) >= mSelectorIndices.length;
        if ((!wrapSelectorWheel || wrappingAllowed) && wrapSelectorWheel != mWrapSelectorWheel) {
            mWrapSelectorWheel = wrapSelectorWheel;
        }
    
private voidshowSoftInput()
Shows the soft input for its input text.

        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
        if (inputMethodManager != null) {
            if (mHasSelectorWheel) {
                mInputText.setVisibility(View.VISIBLE);
            }
            mInputText.requestFocus();
            inputMethodManager.showSoftInput(mInputText, 0);
        }
    
private voidtryComputeMaxWidth()
Computes the max width if no such specified as an attribute.

        if (!mComputeMaxWidth) {
            return;
        }
        int maxTextWidth = 0;
        if (mDisplayedValues == null) {
            float maxDigitWidth = 0;
            for (int i = 0; i <= 9; i++) {
                final float digitWidth = mSelectorWheelPaint.measureText(formatNumberWithLocale(i));
                if (digitWidth > maxDigitWidth) {
                    maxDigitWidth = digitWidth;
                }
            }
            int numberOfDigits = 0;
            int current = mMaxValue;
            while (current > 0) {
                numberOfDigits++;
                current = current / 10;
            }
            maxTextWidth = (int) (numberOfDigits * maxDigitWidth);
        } else {
            final int valueCount = mDisplayedValues.length;
            for (int i = 0; i < valueCount; i++) {
                final float textWidth = mSelectorWheelPaint.measureText(mDisplayedValues[i]);
                if (textWidth > maxTextWidth) {
                    maxTextWidth = (int) textWidth;
                }
            }
        }
        maxTextWidth += mInputText.getPaddingLeft() + mInputText.getPaddingRight();
        if (mMaxWidth != maxTextWidth) {
            if (maxTextWidth > mMinWidth) {
                mMaxWidth = maxTextWidth;
            } else {
                mMaxWidth = mMinWidth;
            }
            invalidate();
        }
    
private booleanupdateInputTextView()
Updates the view of this NumberPicker. If displayValues were specified in the string corresponding to the index specified by the current value will be returned. Otherwise, the formatter specified in {@link #setFormatter} will be used to format the number.

return
Whether the text was updated.

        /*
         * If we don't have displayed values then use the current number else
         * find the correct value in the displayed values for the current
         * number.
         */
        String text = (mDisplayedValues == null) ? formatNumber(mValue)
                : mDisplayedValues[mValue - mMinValue];
        if (!TextUtils.isEmpty(text) && !text.equals(mInputText.getText().toString())) {
            mInputText.setText(text);
            return true;
        }

        return false;
    
private voidvalidateInputTextView(android.view.View v)

        String str = String.valueOf(((TextView) v).getText());
        if (TextUtils.isEmpty(str)) {
            // Restore to the old value as we don't allow empty values
            updateInputTextView();
        } else {
            // Check the new value and ensure it's in range
            int current = getSelectedPos(str.toString());
            setValueInternal(current, true);
        }