Merge "Revamp of the NumberPicker widget."
diff --git a/api/current.txt b/api/current.txt
index e28477c..665b054 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26958,7 +26958,6 @@
     method public void setOnValueChangedListener(android.widget.NumberPicker.OnValueChangeListener);
     method public void setValue(int);
     method public void setWrapSelectorWheel(boolean);
-    field public static final int SELECTOR_WHEEL_ITEM_COUNT = 5; // 0x5
   }
 
   public static abstract interface NumberPicker.Formatter {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 42426b98..b8fbf17 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2679,15 +2679,6 @@
         return child.draw(canvas, this, drawingTime);
     }
 
-    @Override
-    public void requestLayout() {
-        if (mChildrenCount > 0 && getAccessibilityNodeProvider() != null) {
-            throw new IllegalStateException("Views with AccessibilityNodeProvider"
-                    + " can't have children.");
-        }
-        super.requestLayout();
-    }
-
     /**
      * 
      * @param enabled True if children should be drawn with layers, false otherwise.
@@ -3109,11 +3100,6 @@
     private void addViewInner(View child, int index, LayoutParams params,
             boolean preventRequestLayout) {
 
-        if (getAccessibilityNodeProvider() != null) {
-            throw new IllegalStateException("Views with AccessibilityNodeProvider"
-                    + " can't have children.");
-        }
-
         if (mTransition != null) {
             // Don't prevent other add transitions from completing, but cancel remove
             // transitions to let them complete the process before we add to the container
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index fd93980..c5066b6 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -29,8 +29,8 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
+import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
@@ -280,9 +280,7 @@
         reorderSpinners();
 
         // set content descriptions
-        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-            setContentDescriptions();
-        }
+        setContentDescriptions();
     }
 
     /**
@@ -717,20 +715,27 @@
 
     private void setContentDescriptions() {
         // Day
-        String text = mContext.getString(R.string.date_picker_increment_day_button);
-        mDaySpinner.findViewById(R.id.increment).setContentDescription(text);
-        text = mContext.getString(R.string.date_picker_decrement_day_button);
-        mDaySpinner.findViewById(R.id.decrement).setContentDescription(text);
+        trySetContentDescription(mDaySpinner, R.id.increment,
+                R.string.date_picker_increment_day_button);
+        trySetContentDescription(mDaySpinner, R.id.decrement,
+                R.string.date_picker_decrement_day_button);
         // Month
-        text = mContext.getString(R.string.date_picker_increment_month_button);
-        mMonthSpinner.findViewById(R.id.increment).setContentDescription(text);
-        text = mContext.getString(R.string.date_picker_decrement_month_button);
-        mMonthSpinner.findViewById(R.id.decrement).setContentDescription(text);
+        trySetContentDescription(mMonthSpinner, R.id.increment,
+                R.string.date_picker_increment_month_button);
+        trySetContentDescription(mMonthSpinner, R.id.decrement,
+                R.string.date_picker_decrement_month_button);
         // Year
-        text = mContext.getString(R.string.date_picker_increment_year_button);
-        mYearSpinner.findViewById(R.id.increment).setContentDescription(text);
-        text = mContext.getString(R.string.date_picker_decrement_year_button);
-        mYearSpinner.findViewById(R.id.decrement).setContentDescription(text);
+        trySetContentDescription(mYearSpinner, R.id.increment,
+                R.string.date_picker_increment_year_button);
+        trySetContentDescription(mYearSpinner, R.id.decrement,
+                R.string.date_picker_decrement_year_button);
+    }
+
+    private void trySetContentDescription(View root, int viewId, int contDescResId) {
+        View target = root.findViewById(viewId);
+        if (target != null) {
+            target.setContentDescription(mContext.getString(contDescResId));
+        }
     }
 
     private void updateInputState() {
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 3335da0..4e56cd6 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -16,10 +16,6 @@
 
 package android.widget;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
 import android.annotation.Widget;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -48,22 +44,41 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.animation.DecelerateInterpolator;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 
 import com.android.internal.R;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * A widget that enables the user to select a number form a predefined range.
- * The widget presents an input field and up and down buttons for selecting the
- * current value. Pressing/long-pressing the up and down buttons increments and
- * decrements the current value respectively. Touching the input field shows a
- * scroll wheel, which when touched allows direct edit
- * of the current value. Sliding gestures up or down hide the buttons and the
- * input filed, show and rotate the scroll wheel. Flinging is
- * also supported. The widget enables mapping from positions to strings such
- * that, instead of the position index, the corresponding string is displayed.
+ * There are two flavors of this widget and which one is presented to the user
+ * depends on the current theme.
+ * <ul>
+ * <li>
+ * 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.
+ * </li>
+ * <li>
+ * 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.
+ * </li>
+ * </ul>
  * <p>
  * For an example of using this widget, see {@link android.widget.TimePicker}.
  * </p>
@@ -74,7 +89,7 @@
     /**
      * The number of items show in the selector wheel.
      */
-    public static final int SELECTOR_WHEEL_ITEM_COUNT = 5;
+    private static final int SELECTOR_WHEEL_ITEM_COUNT = 3;
 
     /**
      * The default update interval during long press.
@@ -84,7 +99,7 @@
     /**
      * The index of the middle selector item.
      */
-    private static final int SELECTOR_MIDDLE_ITEM_INDEX = 2;
+    private static final int SELECTOR_MIDDLE_ITEM_INDEX = SELECTOR_WHEEL_ITEM_COUNT / 2;
 
     /**
      * The coefficient by which to adjust (divide) the max fling velocity.
@@ -97,19 +112,12 @@
     private static final int SELECTOR_ADJUSTMENT_DURATION_MILLIS = 800;
 
     /**
-     * The duration of scrolling to the next/previous value while changing
-     * the current value by one, i.e. increment or decrement.
+     * The duration of scrolling to the next/previous value while changing the
+     * current value by one, i.e. increment or decrement.
      */
     private static final int CHANGE_CURRENT_BY_ONE_SCROLL_DURATION = 300;
 
     /**
-     * The the delay for showing the input controls after a single tap on the
-     * input text.
-     */
-    private static final int SHOW_INPUT_CONTROLS_DELAY_MILLIS = ViewConfiguration
-            .getDoubleTapTimeout();
-
-    /**
      * The strength of fading in the top and bottom while drawing the selector.
      */
     private static final float TOP_AND_BOTTOM_FADING_EDGE_STRENGTH = 0.9f;
@@ -120,56 +128,31 @@
     private static final int UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT = 2;
 
     /**
-     * In this state the selector wheel is not shown.
+     * The default unscaled distance between the selection dividers.
      */
-    private static final int SELECTOR_WHEEL_STATE_NONE = 0;
+    private static final int UNSCALED_DEFAULT_SELECTION_DIVIDERS_DISTANCE = 48;
 
     /**
-     * In this state the selector wheel is small.
+     * The default unscaled minimal distance for a swipe to be considered a fling.
      */
-    private static final int SELECTOR_WHEEL_STATE_SMALL = 1;
+    private static final int UNSCALED_DEFAULT_MIN_FLING_DISTANCE = 150;
 
     /**
-     * In this state the selector wheel is large.
+     * Coefficient for adjusting touch scroll distance.
      */
-    private static final int SELECTOR_WHEEL_STATE_LARGE = 2;
+    private static final float TOUCH_SCROLL_DECELERATION_COEFFICIENT = 2.5f;
 
     /**
-     * The alpha of the selector wheel when it is bright.
+     * The resource id for the default layout.
      */
-    private static final int SELECTOR_WHEEL_BRIGHT_ALPHA = 255;
-
-    /**
-     * The alpha of the selector wheel when it is dimmed.
-     */
-    private static final int SELECTOR_WHEEL_DIM_ALPHA = 60;
-
-    /**
-     * The alpha for the increment/decrement button when it is transparent.
-     */
-    private static final int BUTTON_ALPHA_TRANSPARENT = 0;
-
-    /**
-     * The alpha for the increment/decrement button when it is opaque.
-     */
-    private static final int BUTTON_ALPHA_OPAQUE = 1;
-
-    /**
-     * The property for setting the selector paint.
-     */
-    private static final String PROPERTY_SELECTOR_PAINT_ALPHA = "selectorPaintAlpha";
-
-    /**
-     * The property for setting the increment/decrement button alpha.
-     */
-    private static final String PROPERTY_BUTTON_ALPHA = "alpha";
+    private static final int DEFAULT_LAYOUT_RESOURCE_ID = R.layout.number_picker;
 
     /**
      * The numbers accepted by the input text's {@link Filter}
      */
     private static final char[] DIGIT_CHARACTERS = new char[] {
             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
-    };
+     };
 
     /**
      * Constant for unspecified size.
@@ -215,6 +198,11 @@
     private final EditText mInputText;
 
     /**
+     * The distance between the two selection dividers.
+     */
+    private final int mSelectionDividersDistance;
+
+    /**
      * The min height of this widget.
      */
     private final int mMinHeight;
@@ -245,6 +233,11 @@
     private final int mTextSize;
 
     /**
+     * The minimal distance for a swipe to be considered a fling.
+     */
+    private final int mMinFlingDistance;
+
+    /**
      * The height of the gap between text elements if the selector wheel.
      */
     private int mSelectorTextGapHeight;
@@ -297,10 +290,7 @@
     /**
      * The selector indices whose value are show by the selector.
      */
-    private final int[] mSelectorIndices = new int[] {
-            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
-            Integer.MIN_VALUE
-    };
+    private final int[] mSelectorIndices = new int[SELECTOR_WHEEL_ITEM_COUNT];
 
     /**
      * The {@link Paint} for drawing the selector.
@@ -343,25 +333,15 @@
     private SetSelectionCommand mSetSelectionCommand;
 
     /**
-     * Handle to the reusable command for adjusting the scroller.
-     */
-    private AdjustScrollerCommand mAdjustScrollerCommand;
-
-    /**
      * Handle to the reusable command for changing the current value from long
      * press by one.
      */
     private ChangeCurrentByOneFromLongPressCommand mChangeCurrentByOneFromLongPressCommand;
 
     /**
-     * {@link Animator} for showing the up/down arrows.
+     * Command for beginning an edit of the current value via IME on long press.
      */
-    private final AnimatorSet mShowInputControlsAnimator;
-
-    /**
-     * {@link Animator} for dimming the selector wheel.
-     */
-    private final Animator mDimSelectorWheelAnimator;
+    private BeginSoftInputOnLongPressCommand mBeginSoftInputOnLongPressCommand;
 
     /**
      * The Y position of the last down event.
@@ -369,24 +349,14 @@
     private float mLastDownEventY;
 
     /**
-     * The Y position of the last motion event.
+     * The time of the last down event.
      */
-    private float mLastMotionEventY;
+    private long mLastDownEventTime;
 
     /**
-     * Flag if to check for double tap and potentially start edit.
+     * The Y position of the last down or move event.
      */
-    private boolean mCheckBeginEditOnUpEvent;
-
-    /**
-     * Flag if to adjust the selector wheel on next up event.
-     */
-    private boolean mAdjustScrollerOnUpEvent;
-
-    /**
-     * The state of the selector wheel.
-     */
-    private int mSelectorWheelState;
+    private float mLastDownOrMoveEventY;
 
     /**
      * Determines speed during touch scrolling.
@@ -419,9 +389,9 @@
     private final int mSolidColor;
 
     /**
-     * Flag indicating if this widget supports flinging.
+     * Flag whether this widget has a selector wheel.
      */
-    private final boolean mFlingable;
+    private final boolean mHasSelectorWheel;
 
     /**
      * Divider for showing item to be selected while scrolling
@@ -434,29 +404,40 @@
     private final int mSelectionDividerHeight;
 
     /**
-     * Reusable {@link Rect} instance.
-     */
-    private final Rect mTempRect = new Rect();
-
-    /**
      * The current scroll state of the number picker.
      */
     private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
 
     /**
-     * The duration of the animation for showing the input controls.
+     * Flag whether to ignore move events - we ignore such when we show in IME
+     * to prevent the content from scrolling.
      */
-    private final long mShowInputControlsAnimimationDuration;
+    private boolean mIngonreMoveEvents;
 
     /**
-     * Flag whether the scoll wheel and the fading edges have been initialized.
+     * Flag whether to show soft input on tap.
      */
-    private boolean mScrollWheelAndFadingEdgesInitialized;
+    private boolean mShowSoftInputOnTap;
 
     /**
-     * The time of the last up event.
+     * The top of the top selection divider.
      */
-    private long mLastUpEventTimeMillis;
+    private int mTopSelectionDividerTop;
+
+    /**
+     * The bottom of the bottom selection divider.
+     */
+    private int mBottomSelectionDividerBottom;
+
+    /**
+     * The virtual id of the last hovered child.
+     */
+    private int mLastHoveredChildVirtualViewId;
+
+    /**
+     * Provider to report to clients the semantic structure of this widget.
+     */
+    private AccessibilityNodeProviderImpl mAccessibilityNodeProvider;
 
     /**
      * Interface to listen for changes of the current value.
@@ -484,7 +465,7 @@
         public static int SCROLL_STATE_IDLE = 0;
 
         /**
-         * The user is scrolling using touch, and their finger is still on the screen.
+         * The user is scrolling using touch, and his finger is still on the screen.
          */
         public static int SCROLL_STATE_TOUCH_SCROLL = 1;
 
@@ -549,58 +530,78 @@
         super(context, attrs, defStyle);
 
         // process style attributes
-        TypedArray attributesArray = context.obtainStyledAttributes(attrs,
-                R.styleable.NumberPicker, defStyle, 0);
+        TypedArray attributesArray = context.obtainStyledAttributes(
+                attrs, R.styleable.NumberPicker, defStyle, 0);
+        final int layoutResId = attributesArray.getResourceId(
+                R.styleable.NumberPicker_internalLayout, DEFAULT_LAYOUT_RESOURCE_ID);
+
+        mHasSelectorWheel = (layoutResId != DEFAULT_LAYOUT_RESOURCE_ID);
+
         mSolidColor = attributesArray.getColor(R.styleable.NumberPicker_solidColor, 0);
-        mFlingable = attributesArray.getBoolean(R.styleable.NumberPicker_flingable, true);
+
         mSelectionDivider = attributesArray.getDrawable(R.styleable.NumberPicker_selectionDivider);
-        int defSelectionDividerHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT,
+
+        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);
+
+        final int defMinFlingDistance = (int) TypedValue.applyDimension(
+                TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_MIN_FLING_DISTANCE,
+                getResources().getDisplayMetrics());
+        mMinFlingDistance = attributesArray.getDimensionPixelSize(
+                R.styleable.NumberPicker_minFlingDistance, defMinFlingDistance);
+
         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);
+
+        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 == Integer.MAX_VALUE);
-        attributesArray.recycle();
 
-        mShowInputControlsAnimimationDuration = getResources().getInteger(
-                R.integer.config_longAnimTime);
+        mComputeMaxWidth = (mMaxWidth == Integer.MAX_VALUE);
+
+        attributesArray.recycle();
 
         // 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(false);
-        setSelectorWheelState(SELECTOR_WHEEL_STATE_NONE);
+        setWillNotDraw(!mHasSelectorWheel);
 
         LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(R.layout.number_picker, this, true);
+        inflater.inflate(layoutResId, this, true);
 
         OnClickListener onClickListener = new OnClickListener() {
             public void onClick(View v) {
                 hideSoftInput();
                 mInputText.clearFocus();
                 if (v.getId() == R.id.increment) {
-                    changeCurrentByOne(true);
+                    changeValueByOne(true);
                 } else {
-                    changeCurrentByOne(false);
+                    changeValueByOne(false);
                 }
             }
         };
@@ -610,23 +611,31 @@
                 hideSoftInput();
                 mInputText.clearFocus();
                 if (v.getId() == R.id.increment) {
-                    postChangeCurrentByOneFromLongPress(true);
+                    postChangeCurrentByOneFromLongPress(true, 0);
                 } else {
-                    postChangeCurrentByOneFromLongPress(false);
+                    postChangeCurrentByOneFromLongPress(false, 0);
                 }
                 return true;
             }
         };
 
         // increment button
-        mIncrementButton = (ImageButton) findViewById(R.id.increment);
-        mIncrementButton.setOnClickListener(onClickListener);
-        mIncrementButton.setOnLongClickListener(onLongClickListener);
+        if (!mHasSelectorWheel) {
+            mIncrementButton = (ImageButton) findViewById(R.id.increment);
+            mIncrementButton.setOnClickListener(onClickListener);
+            mIncrementButton.setOnLongClickListener(onLongClickListener);
+        } else {
+            mIncrementButton = null;
+        }
 
         // decrement button
-        mDecrementButton = (ImageButton) findViewById(R.id.decrement);
-        mDecrementButton.setOnClickListener(onClickListener);
-        mDecrementButton.setOnLongClickListener(onLongClickListener);
+        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);
@@ -648,7 +657,6 @@
         mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);
 
         // initialize constants
-        mTouchSlop = ViewConfiguration.getTapTimeout();
         ViewConfiguration configuration = ViewConfiguration.get(context);
         mTouchSlop = configuration.getScaledTouchSlop();
         mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity();
@@ -667,69 +675,22 @@
         paint.setColor(color);
         mSelectorWheelPaint = paint;
 
-        // create the animator for showing the input controls
-        mDimSelectorWheelAnimator = ObjectAnimator.ofInt(this, PROPERTY_SELECTOR_PAINT_ALPHA,
-                SELECTOR_WHEEL_BRIGHT_ALPHA, SELECTOR_WHEEL_DIM_ALPHA);
-        final ObjectAnimator showIncrementButton = ObjectAnimator.ofFloat(mIncrementButton,
-                PROPERTY_BUTTON_ALPHA, BUTTON_ALPHA_TRANSPARENT, BUTTON_ALPHA_OPAQUE);
-        final ObjectAnimator showDecrementButton = ObjectAnimator.ofFloat(mDecrementButton,
-                PROPERTY_BUTTON_ALPHA, BUTTON_ALPHA_TRANSPARENT, BUTTON_ALPHA_OPAQUE);
-        mShowInputControlsAnimator = new AnimatorSet();
-        mShowInputControlsAnimator.playTogether(mDimSelectorWheelAnimator, showIncrementButton,
-                showDecrementButton);
-        mShowInputControlsAnimator.addListener(new AnimatorListenerAdapter() {
-            private boolean mCanceled = false;
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (!mCanceled) {
-                    // if canceled => we still want the wheel drawn
-                    setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
-                }
-                mCanceled = false;
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                if (mShowInputControlsAnimator.isRunning()) {
-                    mCanceled = true;
-                }
-            }
-        });
-
         // create the fling and adjust scrollers
         mFlingScroller = new Scroller(getContext(), null, true);
         mAdjustScroller = new Scroller(getContext(), new DecelerateInterpolator(2.5f));
 
         updateInputTextView();
-        updateIncrementAndDecrementButtonsVisibilityState();
-
-        if (mFlingable) {
-           if (isInEditMode()) {
-               setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
-           } else {
-                // Start with shown selector wheel and hidden controls. When made
-                // visible hide the selector and fade-in the controls to suggest
-                // fling interaction.
-                setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
-                hideInputControls();
-           }
-        }
     }
 
     @Override
     protected void onLayout(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();
 
-        // Increment button at the top.
-        final int inctBtnMsrdWdth = mIncrementButton.getMeasuredWidth();
-        final int incrBtnLeft = (msrdWdth - inctBtnMsrdWdth) / 2;
-        final int incrBtnTop = 0;
-        final int incrBtnRight = incrBtnLeft + inctBtnMsrdWdth;
-        final int incrBtnBottom = incrBtnTop + mIncrementButton.getMeasuredHeight();
-        mIncrementButton.layout(incrBtnLeft, incrBtnTop, incrBtnRight, incrBtnBottom);
-
         // Input text centered horizontally.
         final int inptTxtMsrdWdth = mInputText.getMeasuredWidth();
         final int inptTxtMsrdHght = mInputText.getMeasuredHeight();
@@ -739,24 +700,23 @@
         final int inptTxtBottom = inptTxtTop + inptTxtMsrdHght;
         mInputText.layout(inptTxtLeft, inptTxtTop, inptTxtRight, inptTxtBottom);
 
-        // Decrement button at the top.
-        final int decrBtnMsrdWdth = mIncrementButton.getMeasuredWidth();
-        final int decrBtnLeft = (msrdWdth - decrBtnMsrdWdth) / 2;
-        final int decrBtnTop = msrdHght - mDecrementButton.getMeasuredHeight();
-        final int decrBtnRight = decrBtnLeft + decrBtnMsrdWdth;
-        final int decrBtnBottom = msrdHght;
-        mDecrementButton.layout(decrBtnLeft, decrBtnTop, decrBtnRight, decrBtnBottom);
-
-        if (!mScrollWheelAndFadingEdgesInitialized) {
-            mScrollWheelAndFadingEdgesInitialized = true;
+        if (changed) {
             // need to do all this when we know our size
             initializeSelectorWheel();
             initializeFadingEdges();
+            mTopSelectionDividerTop = (getHeight() - mSelectionDividersDistance) / 2
+                    - mSelectionDividerHeight;
+            mBottomSelectionDividerBottom = mTopSelectionDividerTop + 2 * mSelectionDividerHeight
+                    + mSelectionDividersDistance;
         }
     }
 
     @Override
     protected void onMeasure(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);
@@ -769,120 +729,143 @@
         setMeasuredDimension(widthSize, heightSize);
     }
 
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent event) {
-        if (!isEnabled() || !mFlingable) {
-            return false;
-        }
-        switch (event.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN:
-                mLastMotionEventY = mLastDownEventY = event.getY();
-                removeAllCallbacks();
-                mShowInputControlsAnimator.cancel();
-                mDimSelectorWheelAnimator.cancel();
-                mCheckBeginEditOnUpEvent = false;
-                mAdjustScrollerOnUpEvent = true;
-                if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
-                    mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
-                    boolean scrollersFinished = mFlingScroller.isFinished()
-                            && mAdjustScroller.isFinished();
-                    if (!scrollersFinished) {
-                        mFlingScroller.forceFinished(true);
-                        mAdjustScroller.forceFinished(true);
-                        onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
-                    }
-                    mCheckBeginEditOnUpEvent = scrollersFinished;
-                    mAdjustScrollerOnUpEvent = true;
-                    hideSoftInput();
-                    hideInputControls();
-                    return true;
+    /**
+     * 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.
+     */
+    private boolean moveToFinalScrollerPosition(Scroller scroller) {
+        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;
                 }
-                if (isEventInVisibleViewHitRect(event, mIncrementButton)
-                        || isEventInVisibleViewHitRect(event, mDecrementButton)) {
-                    return false;
-                }
-                mAdjustScrollerOnUpEvent = false;
-                setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
-                hideSoftInput();
-                hideInputControls();
-                return true;
-            case MotionEvent.ACTION_MOVE:
-                float currentMoveY = event.getY();
-                int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
-                if (deltaDownY > mTouchSlop) {
-                    mCheckBeginEditOnUpEvent = false;
-                    onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
-                    setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
-                    hideSoftInput();
-                    hideInputControls();
-                    return true;
-                }
-                break;
+            }
+            amountToScroll += overshootAdjustment;
+            scrollBy(0, amountToScroll);
+            return true;
         }
         return false;
     }
 
     @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        if (!isEnabled()) {
+    public boolean onInterceptTouchEvent(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();
+                mIngonreMoveEvents = false;
+                mShowSoftInputOnTap = false;
+                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 {
+                    mShowSoftInputOnTap = true;
+                    postBeginSoftInputOnLongPressCommand();
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        if (!isEnabled() || !mHasSelectorWheel) {
             return false;
         }
         if (mVelocityTracker == null) {
             mVelocityTracker = VelocityTracker.obtain();
         }
-        mVelocityTracker.addMovement(ev);
-        int action = ev.getActionMasked();
+        mVelocityTracker.addMovement(event);
+        int action = event.getActionMasked();
         switch (action) {
-            case MotionEvent.ACTION_MOVE:
-                float currentMoveY = ev.getY();
-                if (mCheckBeginEditOnUpEvent
-                        || mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
+            case MotionEvent.ACTION_MOVE: {
+                if (mIngonreMoveEvents) {
+                    break;
+                }
+                float currentMoveY = event.getY();
+                if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                     int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
                     if (deltaDownY > mTouchSlop) {
-                        mCheckBeginEditOnUpEvent = false;
+                        removeAllCallbacks();
                         onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                     }
+                } else {
+                    int deltaMoveY = (int) ((currentMoveY - mLastDownOrMoveEventY)
+                            / TOUCH_SCROLL_DECELERATION_COEFFICIENT);
+                    scrollBy(0, deltaMoveY);
+                    invalidate();
                 }
-                int deltaMoveY = (int) (currentMoveY - mLastMotionEventY);
-                scrollBy(0, deltaMoveY);
-                invalidate();
-                mLastMotionEventY = currentMoveY;
-                break;
-            case MotionEvent.ACTION_UP:
-                if (mCheckBeginEditOnUpEvent) {
-                    mCheckBeginEditOnUpEvent = false;
-                    final long deltaTapTimeMillis = ev.getEventTime() - mLastUpEventTimeMillis;
-                    if (deltaTapTimeMillis < ViewConfiguration.getDoubleTapTimeout()) {
-                        setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
-                        showInputControls(mShowInputControlsAnimimationDuration);
-                        mInputText.requestFocus();
-                        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
-                        if (inputMethodManager != null) {
-                            inputMethodManager.showSoftInput(mInputText, 0);
-                        }
-                        mLastUpEventTimeMillis = ev.getEventTime();
-                        return true;
-                    }
-                }
+                mLastDownOrMoveEventY = currentMoveY;
+            } break;
+            case MotionEvent.ACTION_UP: {
+                removeBeginSoftInputCommand();
+                removeChangeCurrentByOneFromLongPress();
                 VelocityTracker velocityTracker = mVelocityTracker;
                 velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
                 int initialVelocity = (int) velocityTracker.getYVelocity();
                 if (Math.abs(initialVelocity) > mMinimumFlingVelocity) {
-                    fling(initialVelocity);
+                    int deltaMove = (int) (event.getY() - mLastDownEventY);
+                    int absDeltaMoveY = Math.abs(deltaMove);
+                    if (absDeltaMoveY > mMinFlingDistance) {
+                        fling(initialVelocity);
+                    } else {
+                        changeValueByOne(deltaMove < 0);
+                    }
                     onScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
                 } else {
-                    if (mAdjustScrollerOnUpEvent) {
-                        if (mFlingScroller.isFinished() && mAdjustScroller.isFinished()) {
-                            postAdjustScrollerCommand(0);
+                    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 {
+                            int selectorIndexOffset = (eventY / mSelectorElementHeight)
+                                    - SELECTOR_MIDDLE_ITEM_INDEX;
+                            if (selectorIndexOffset > 0) {
+                                changeValueByOne(true);
+                            } else if (selectorIndexOffset < 0) {
+                                changeValueByOne(false);
+                            }
                         }
                     } else {
-                        postAdjustScrollerCommand(SHOW_INPUT_CONTROLS_DELAY_MILLIS);
+                        ensureScrollWheelAdjusted();
                     }
+                    onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                 }
                 mVelocityTracker.recycle();
                 mVelocityTracker = null;
-                mLastUpEventTimeMillis = ev.getEventTime();
-                break;
+            } break;
         }
         return true;
     }
@@ -891,12 +874,6 @@
     public boolean dispatchTouchEvent(MotionEvent event) {
         final int action = event.getActionMasked();
         switch (action) {
-            case MotionEvent.ACTION_MOVE:
-                if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
-                    removeAllCallbacks();
-                    forceCompleteChangeCurrentByOneViaScroll();
-                }
-                break;
             case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
                 removeAllCallbacks();
@@ -907,27 +884,75 @@
 
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
-        int keyCode = event.getKeyCode();
-        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) {
-            removeAllCallbacks();
+        final int keyCode = event.getKeyCode();
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_DPAD_CENTER:
+            case KeyEvent.KEYCODE_ENTER:
+                removeAllCallbacks();
+                break;
         }
         return super.dispatchKeyEvent(event);
     }
 
     @Override
     public boolean dispatchTrackballEvent(MotionEvent event) {
-        int action = event.getActionMasked();
-        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
-            removeAllCallbacks();
+        final int action = event.getActionMasked();
+        switch (action) {
+            case MotionEvent.ACTION_CANCEL:
+            case MotionEvent.ACTION_UP:
+                removeAllCallbacks();
+                break;
         }
         return super.dispatchTrackballEvent(event);
     }
 
     @Override
-    public void computeScroll() {
-        if (mSelectorWheelState == SELECTOR_WHEEL_STATE_NONE) {
-            return;
+    protected boolean dispatchHoverEvent(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;
+                } 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;
+                    }
+                } break;
+                case MotionEvent.ACTION_HOVER_EXIT: {
+                    provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId,
+                            AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+                    mLastHoveredChildVirtualViewId = View.NO_ID;
+                } break;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void computeScroll() {
         Scroller scroller = mFlingScroller;
         if (scroller.isFinished()) {
             scroller = mAdjustScroller;
@@ -952,16 +977,17 @@
     @Override
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
-        mIncrementButton.setEnabled(enabled);
-        mDecrementButton.setEnabled(enabled);
+        if (!mHasSelectorWheel) {
+            mIncrementButton.setEnabled(enabled);
+        }
+        if (!mHasSelectorWheel) {
+            mDecrementButton.setEnabled(enabled);
+        }
         mInputText.setEnabled(enabled);
     }
 
     @Override
     public void scrollBy(int x, int y) {
-        if (mSelectorWheelState == SELECTOR_WHEEL_STATE_NONE) {
-            return;
-        }
         int[] selectorIndices = mSelectorIndices;
         if (!mWrapSelectorWheel && y > 0
                 && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
@@ -977,7 +1003,7 @@
         while (mCurrentScrollOffset - mInitialScrollOffset > mSelectorTextGapHeight) {
             mCurrentScrollOffset -= mSelectorElementHeight;
             decrementSelectorIndices(selectorIndices);
-            changeCurrent(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX]);
+            setValueInternal(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX], true);
             if (!mWrapSelectorWheel && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
                 mCurrentScrollOffset = mInitialScrollOffset;
             }
@@ -985,7 +1011,7 @@
         while (mCurrentScrollOffset - mInitialScrollOffset < -mSelectorTextGapHeight) {
             mCurrentScrollOffset += mSelectorElementHeight;
             incrementSelectorIndices(selectorIndices);
-            changeCurrent(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX]);
+            setValueInternal(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX], true);
             if (!mWrapSelectorWheel && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] >= mMaxValue) {
                 mCurrentScrollOffset = mInitialScrollOffset;
             }
@@ -1024,8 +1050,7 @@
      *
      * @param formatter The formatter object. If formatter is <code>null</code>,
      *            {@link String#valueOf(int)} will be used.
-     *
-     * @see #setDisplayedValues(String[])
+     *@see #setDisplayedValues(String[])
      */
     public void setFormatter(Formatter formatter) {
         if (formatter == mFormatter) {
@@ -1068,26 +1093,35 @@
         if (mValue == value) {
             return;
         }
-        if (value < mMinValue) {
-            value = mWrapSelectorWheel ? mMaxValue : mMinValue;
-        }
-        if (value > mMaxValue) {
-            value = mWrapSelectorWheel ? mMinValue : mMaxValue;
-        }
-        mValue = value;
+        setValueInternal(value, false);
         initializeSelectorWheelIndices();
-        updateInputTextView();
-        updateIncrementAndDecrementButtonsVisibilityState();
         invalidate();
     }
 
     /**
-     * Hides the soft input of it is active for the input text.
+     * Shows the soft input for its input text.
+     */
+    private void showSoftInput() {
+        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
+        if (inputMethodManager != null) {
+            if (mHasSelectorWheel) {
+                mInputText.setVisibility(View.VISIBLE);
+            }
+            mInputText.requestFocus();
+            inputMethodManager.showSoftInput(mInputText, 0);
+        }
+    }
+
+    /**
+     * Hides the soft input if it is active for the input text.
      */
     private void hideSoftInput() {
         InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
         if (inputMethodManager != null && inputMethodManager.isActive(mInputText)) {
             inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+            if (mHasSelectorWheel) {
+                mInputText.setVisibility(View.INVISIBLE);
+            }
         }
     }
 
@@ -1151,23 +1185,22 @@
      * wrap around the {@link NumberPicker#getMinValue()} and
      * {@link NumberPicker#getMaxValue()} values.
      * <p>
-     * By default if the range (max - min) is more than five (the number of
-     * items shown on the selector wheel) the selector wheel wrapping is
-     * enabled.
+     * 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.
      * </p>
      * <p>
-     * <strong>Note:</strong> If the number of items, i.e. the range
-     * ({@link #getMaxValue()} - {@link #getMinValue()}) is less than
-     * {@link #SELECTOR_WHEEL_ITEM_COUNT}, the selector wheel will not
-     * wrap. Hence, in such a case calling this method is a NOP.
+     * <strong>Note:</strong> 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.
      * </p>
+     *
      * @param wrapSelectorWheel Whether to wrap.
      */
     public void setWrapSelectorWheel(boolean wrapSelectorWheel) {
         final boolean wrappingAllowed = (mMaxValue - mMinValue) >= mSelectorIndices.length;
         if ((!wrapSelectorWheel || wrappingAllowed) && wrapSelectorWheel != mWrapSelectorWheel) {
             mWrapSelectorWheel = wrapSelectorWheel;
-            updateIncrementAndDecrementButtonsVisibilityState();
         }
     }
 
@@ -1224,6 +1257,7 @@
         initializeSelectorWheelIndices();
         updateInputTextView();
         tryComputeMaxWidth();
+        invalidate();
     }
 
     /**
@@ -1256,6 +1290,7 @@
         initializeSelectorWheelIndices();
         updateInputTextView();
         tryComputeMaxWidth();
+        invalidate();
     }
 
     /**
@@ -1300,102 +1335,49 @@
     }
 
     @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        // make sure we show the controls only the very
-        // first time the user sees this widget
-        if (mFlingable && !isInEditMode()) {
-            // animate a bit slower the very first time
-            showInputControls(mShowInputControlsAnimimationDuration * 2);
-        }
-    }
-
-    @Override
     protected void onDetachedFromWindow() {
         removeAllCallbacks();
     }
 
     @Override
-    protected void dispatchDraw(Canvas canvas) {
-        // There is a good reason for doing this. See comments in draw().
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        // Dispatch draw to our children only if we are not currently running
-        // the animation for simultaneously dimming the scroll wheel and
-        // showing in the buttons. This class takes advantage of the View
-        // implementation of fading edges effect to draw the selector wheel.
-        // However, in View.draw(), the fading is applied after all the children
-        // have been drawn and we do not want this fading to be applied to the
-        // buttons. Therefore, we draw our children after we have completed
-        // drawing ourselves.
-        super.draw(canvas);
-
-        // Draw our children if we are not showing the selector wheel of fading
-        // it out
-        if (mShowInputControlsAnimator.isRunning()
-                || mSelectorWheelState != SELECTOR_WHEEL_STATE_LARGE) {
-            long drawTime = getDrawingTime();
-            for (int i = 0, count = getChildCount(); i < count; i++) {
-                View child = getChildAt(i);
-                if (!child.isShown()) {
-                    continue;
-                }
-                drawChild(canvas, getChildAt(i), drawTime);
-            }
-        }
-    }
-
-    @Override
     protected void onDraw(Canvas canvas) {
-        if (mSelectorWheelState == SELECTOR_WHEEL_STATE_NONE) {
+        if (!mHasSelectorWheel) {
+            super.onDraw(canvas);
             return;
         }
-
         float x = (mRight - mLeft) / 2;
         float y = mCurrentScrollOffset;
 
-        final int restoreCount = canvas.save();
-
-        if (mSelectorWheelState == SELECTOR_WHEEL_STATE_SMALL) {
-            Rect clipBounds = canvas.getClipBounds();
-            clipBounds.inset(0, mSelectorElementHeight);
-            canvas.clipRect(clipBounds);
-        }
-
         // 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.
+            // 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 (i != SELECTOR_MIDDLE_ITEM_INDEX || mInputText.getVisibility() != VISIBLE) {
                 canvas.drawText(scrollSelectorValue, x, y, mSelectorWheelPaint);
             }
             y += mSelectorElementHeight;
         }
 
-        // draw the selection dividers (only if scrolling and drawable specified)
+        // draw the selection dividers
         if (mSelectionDivider != null) {
             // draw the top divider
-            int topOfTopDivider =
-                (getHeight() - mSelectorElementHeight - mSelectionDividerHeight) / 2;
+            int topOfTopDivider = mTopSelectionDividerTop;
             int bottomOfTopDivider = topOfTopDivider + mSelectionDividerHeight;
             mSelectionDivider.setBounds(0, topOfTopDivider, mRight, bottomOfTopDivider);
             mSelectionDivider.draw(canvas);
 
             // draw the bottom divider
-            int topOfBottomDivider =  topOfTopDivider + mSelectorElementHeight;
-            int bottomOfBottomDivider = bottomOfTopDivider + mSelectorElementHeight;
+            int bottomOfBottomDivider = mBottomSelectionDividerBottom;
+            int topOfBottomDivider = bottomOfBottomDivider - mSelectionDividerHeight;
             mSelectionDivider.setBounds(0, topOfBottomDivider, mRight, bottomOfBottomDivider);
             mSelectionDivider.draw(canvas);
         }
-
-        canvas.restoreToCount(restoreCount);
     }
 
     @Override
@@ -1408,12 +1390,20 @@
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
         event.setClassName(NumberPicker.class.getName());
+        event.setScrollable(true);
+        event.setScrollY((mMinValue + mValue) * mSelectorElementHeight);
+        event.setMaxScrollY((mMaxValue - mMinValue) * mSelectorElementHeight);
     }
 
     @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setClassName(NumberPicker.class.getName());
+    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
+        if (!mHasSelectorWheel) {
+            return super.getAccessibilityNodeProvider();
+        }
+        if (mAccessibilityNodeProvider == null) {
+            mAccessibilityNodeProvider = new AccessibilityNodeProviderImpl();
+        }
+        return mAccessibilityNodeProvider;
     }
 
     /**
@@ -1442,17 +1432,17 @@
     }
 
     /**
-     * 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.
+     * 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.
      */
-    private int resolveSizeAndStateRespectingMinSize(int minSize, int measuredSize,
-            int measureSpec) {
+    private int resolveSizeAndStateRespectingMinSize(
+            int minSize, int measuredSize, int measureSpec) {
         if (minSize != SIZE_UNSPECIFIED) {
             final int desiredWidth = Math.max(minSize, measuredSize);
             return resolveSizeAndState(desiredWidth, measureSpec, 0);
@@ -1462,8 +1452,8 @@
     }
 
     /**
-     * Resets the selector indices and clear the cached
-     * string representation of these indices.
+     * Resets the selector indices and clear the cached string representation of
+     * these indices.
      */
     private void initializeSelectorWheelIndices() {
         mSelectorIndexToStringCache.clear();
@@ -1480,39 +1470,44 @@
     }
 
     /**
-     * Sets the current value of this NumberPicker, and sets mPrevious to the
-     * previous value. If current is greater than mEnd less than mStart, the
-     * value of mCurrent is wrapped around. Subclasses can override this to
-     * change the wrapping behavior
+     * Sets the current value of this NumberPicker.
      *
-     * @param current the new value of the NumberPicker
+     * @param current The new value of the NumberPicker.
+     * @param notifyChange Whether to notify if the current value changed.
      */
-    private void changeCurrent(int current) {
+    private void setValueInternal(int current, boolean notifyChange) {
         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;
-        setValue(current);
-        notifyChange(previous, current);
+        mValue = current;
+        updateInputTextView();
+        if (notifyChange) {
+            notifyChange(previous, current);
+        }
     }
 
     /**
      * 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.
      */
-    private void changeCurrentByOne(boolean increment) {
-        if (mFlingable) {
-            mDimSelectorWheelAnimator.cancel();
+     private void changeValueByOne(boolean increment) {
+        if (mHasSelectorWheel) {
             mInputText.setVisibility(View.INVISIBLE);
-            mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
+            if (!moveToFinalScrollerPosition(mFlingScroller)) {
+                moveToFinalScrollerPosition(mAdjustScroller);
+            }
             mPreviousScrollerY = 0;
-            forceCompleteChangeCurrentByOneViaScroll();
             if (increment) {
                 mFlingScroller.startScroll(0, 0, 0, -mSelectorElementHeight,
                         CHANGE_CURRENT_BY_ONE_SCROLL_DURATION);
@@ -1523,81 +1518,26 @@
             invalidate();
         } else {
             if (increment) {
-                changeCurrent(mValue + 1);
+                setValueInternal(mValue + 1, true);
             } else {
-                changeCurrent(mValue - 1);
+                setValueInternal(mValue - 1, true);
             }
         }
     }
 
-    /**
-     * Ensures that if we are in the process of changing the current value
-     * by one via scrolling the scroller gets to its final state and the
-     * value is updated.
-     */
-    private void forceCompleteChangeCurrentByOneViaScroll() {
-        Scroller scroller = mFlingScroller;
-        if (!scroller.isFinished()) {
-            final int yBeforeAbort = scroller.getCurrY();
-            scroller.abortAnimation();
-            final int yDelta = scroller.getCurrY() - yBeforeAbort;
-            scrollBy(0, yDelta);
-        }
-    }
-
-    /**
-     * Sets the <code>alpha</code> of the {@link Paint} for drawing the selector
-     * wheel.
-     */
-    @SuppressWarnings("unused")
-    // Called via reflection
-    private void setSelectorPaintAlpha(int alpha) {
-        mSelectorWheelPaint.setAlpha(alpha);
-        invalidate();
-    }
-
-    /**
-     * @return If the <code>event</code> is in the visible <code>view</code>.
-     */
-    private boolean isEventInVisibleViewHitRect(MotionEvent event, View view) {
-        if (view.getVisibility() == VISIBLE) {
-            view.getHitRect(mTempRect);
-            return mTempRect.contains((int) event.getX(), (int) event.getY());
-        }
-        return false;
-    }
-
-    /**
-     * Sets the <code>selectorWheelState</code>.
-     */
-    private void setSelectorWheelState(int selectorWheelState) {
-        mSelectorWheelState = selectorWheelState;
-        if (selectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
-            mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
-        }
-
-        if (mFlingable && selectorWheelState == SELECTOR_WHEEL_STATE_LARGE
-                && AccessibilityManager.getInstance(mContext).isEnabled()) {
-            AccessibilityManager.getInstance(mContext).interrupt();
-            String text = mContext.getString(R.string.number_picker_increment_scroll_action);
-            mInputText.setContentDescription(text);
-            mInputText.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
-            mInputText.setContentDescription(null);
-        }
-    }
-
     private void initializeSelectorWheel() {
         initializeSelectorWheelIndices();
         int[] selectorIndices = mSelectorIndices;
         int totalTextHeight = selectorIndices.length * mTextSize;
         float totalTextGapHeight = (mBottom - mTop) - totalTextHeight;
-        float textGapCount = selectorIndices.length - 1;
+        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
+        // 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);
+        mInitialScrollOffset = editTextTextPosition
+                - (mSelectorElementHeight * SELECTOR_MIDDLE_ITEM_INDEX);
         mCurrentScrollOffset = mInitialScrollOffset;
         updateInputTextView();
     }
@@ -1612,16 +1552,14 @@
      */
     private void onScrollerFinished(Scroller scroller) {
         if (scroller == mFlingScroller) {
-            if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
-                postAdjustScrollerCommand(0);
-                onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
-            } else {
+            if (!ensureScrollWheelAdjusted()) {
                 updateInputTextView();
-                fadeSelectorWheel(mShowInputControlsAnimimationDuration);
             }
+            onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
         } else {
-            updateInputTextView();
-            showInputControls(mShowInputControlsAnimimationDuration);
+            if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
+                updateInputTextView();
+            }
         }
     }
 
@@ -1654,56 +1592,6 @@
     }
 
     /**
-     * Hides the input controls which is the up/down arrows and the text field.
-     */
-    private void hideInputControls() {
-        mShowInputControlsAnimator.cancel();
-        mIncrementButton.setVisibility(INVISIBLE);
-        mDecrementButton.setVisibility(INVISIBLE);
-        mInputText.setVisibility(INVISIBLE);
-    }
-
-    /**
-     * Show the input controls by making them visible and animating the alpha
-     * property up/down arrows.
-     *
-     * @param animationDuration The duration of the animation.
-     */
-    private void showInputControls(long animationDuration) {
-        updateIncrementAndDecrementButtonsVisibilityState();
-        mInputText.setVisibility(VISIBLE);
-        mShowInputControlsAnimator.setDuration(animationDuration);
-        mShowInputControlsAnimator.start();
-    }
-
-    /**
-     * Fade the selector wheel via an animation.
-     *
-     * @param animationDuration The duration of the animation.
-     */
-    private void fadeSelectorWheel(long animationDuration) {
-        mInputText.setVisibility(VISIBLE);
-        mDimSelectorWheelAnimator.setDuration(animationDuration);
-        mDimSelectorWheelAnimator.start();
-    }
-
-    /**
-     * Updates the visibility state of the increment and decrement buttons.
-     */
-    private void updateIncrementAndDecrementButtonsVisibilityState() {
-        if (mWrapSelectorWheel || mValue < mMaxValue) {
-            mIncrementButton.setVisibility(VISIBLE);
-        } else {
-            mIncrementButton.setVisibility(INVISIBLE);
-        }
-        if (mWrapSelectorWheel || mValue > mMinValue) {
-            mDecrementButton.setVisibility(VISIBLE);
-        } else {
-            mDecrementButton.setVisibility(INVISIBLE);
-        }
-    }
-
-    /**
      * @return The wrapped index <code>selectorIndex</code> value.
      */
     private int getWrappedSelectorIndex(int selectorIndex) {
@@ -1749,8 +1637,7 @@
 
     /**
      * Ensures we have a cached string representation of the given <code>
-     * selectorIndex</code>
-     * to avoid multiple instantiations of the same string.
+     * selectorIndex</code> to avoid multiple instantiations of the same string.
      */
     private void ensureCachedScrollSelectorValue(int selectorIndex) {
         SparseArray<String> cache = mSelectorIndexToStringCache;
@@ -1783,7 +1670,7 @@
         } else {
             // Check the new value and ensure it's in range
             int current = getSelectedPos(str.toString());
-            changeCurrent(current);
+            setValueInternal(current, true);
         }
     }
 
@@ -1792,25 +1679,23 @@
      * 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.
      */
-    private void updateInputTextView() {
+    private boolean updateInputTextView() {
         /*
          * 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.
          */
-        if (mDisplayedValues == null) {
-            mInputText.setText(formatNumber(mValue));
-        } else {
-            mInputText.setText(mDisplayedValues[mValue - mMinValue]);
+        String text = (mDisplayedValues == null) ? formatNumber(mValue)
+                : mDisplayedValues[mValue - mMinValue];
+        if (!TextUtils.isEmpty(text) && !text.equals(mInputText.getText().toString())) {
+            mInputText.setText(text);
+            return true;
         }
-        mInputText.setSelection(mInputText.getText().length());
 
-        if (mFlingable && AccessibilityManager.getInstance(mContext).isEnabled()) {
-            String text = mContext.getString(R.string.number_picker_increment_scroll_mode,
-                    mInputText.getText());
-            mInputText.setContentDescription(text);
-        }
+        return false;
     }
 
     /**
@@ -1828,14 +1713,45 @@
      *
      * @param increment Whether to increment or decrement the value.
      */
-    private void postChangeCurrentByOneFromLongPress(boolean increment) {
-        mInputText.clearFocus();
-        removeAllCallbacks();
+    private void postChangeCurrentByOneFromLongPress(boolean increment, long delayMillis) {
         if (mChangeCurrentByOneFromLongPressCommand == null) {
             mChangeCurrentByOneFromLongPressCommand = new ChangeCurrentByOneFromLongPressCommand();
+        } else {
+            removeCallbacks(mChangeCurrentByOneFromLongPressCommand);
         }
-        mChangeCurrentByOneFromLongPressCommand.setIncrement(increment);
-        post(mChangeCurrentByOneFromLongPressCommand);
+        mChangeCurrentByOneFromLongPressCommand.setStep(increment);
+        postDelayed(mChangeCurrentByOneFromLongPressCommand, delayMillis);
+    }
+
+    /**
+     * Removes the command for changing the current value by one.
+     */
+    private void removeChangeCurrentByOneFromLongPress() {
+        if (mChangeCurrentByOneFromLongPressCommand != null) {
+            removeCallbacks(mChangeCurrentByOneFromLongPressCommand);
+        }
+    }
+
+    /**
+     * Posts a command for beginning an edit of the current value via IME on
+     * long press.
+     */
+    private void postBeginSoftInputOnLongPressCommand() {
+        if (mBeginSoftInputOnLongPressCommand == null) {
+            mBeginSoftInputOnLongPressCommand = new BeginSoftInputOnLongPressCommand();
+        } else {
+            removeCallbacks(mBeginSoftInputOnLongPressCommand);
+        }
+        postDelayed(mBeginSoftInputOnLongPressCommand, ViewConfiguration.getLongPressTimeout());
+    }
+
+    /**
+     * Removes the command for beginning an edit of the current value via IME.
+     */
+    private void removeBeginSoftInputCommand() {
+        if (mBeginSoftInputOnLongPressCommand != null) {
+            removeCallbacks(mBeginSoftInputOnLongPressCommand);
+        }
     }
 
     /**
@@ -1845,12 +1761,12 @@
         if (mChangeCurrentByOneFromLongPressCommand != null) {
             removeCallbacks(mChangeCurrentByOneFromLongPressCommand);
         }
-        if (mAdjustScrollerCommand != null) {
-            removeCallbacks(mAdjustScrollerCommand);
-        }
         if (mSetSelectionCommand != null) {
             removeCallbacks(mSetSelectionCommand);
         }
+        if (mBeginSoftInputOnLongPressCommand != null) {
+            removeCallbacks(mBeginSoftInputOnLongPressCommand);
+        }
     }
 
     /**
@@ -1888,8 +1804,7 @@
 
     /**
      * Posts an {@link SetSelectionCommand} from the given <code>selectionStart
-     * </code> to
-     * <code>selectionEnd</code>.
+     * </code> to <code>selectionEnd</code>.
      */
     private void postSetSelectionCommand(int selectionStart, int selectionEnd) {
         if (mSetSelectionCommand == null) {
@@ -1903,20 +1818,6 @@
     }
 
     /**
-     * Posts an {@link AdjustScrollerCommand} within the given <code>
-     * delayMillis</code>
-     * .
-     */
-    private void postAdjustScrollerCommand(int delayMillis) {
-        if (mAdjustScrollerCommand == null) {
-            mAdjustScrollerCommand = new AdjustScrollerCommand();
-        } else {
-            removeCallbacks(mAdjustScrollerCommand);
-        }
-        postDelayed(mAdjustScrollerCommand, delayMillis);
-    }
-
-    /**
      * Filter for accepting only valid indices or prefixes of the string
      * representation of valid indices.
      */
@@ -1934,8 +1835,8 @@
         }
 
         @Override
-        public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
-                int dstart, int dend) {
+        public CharSequence filter(
+                CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
             if (mDisplayedValues == null) {
                 CharSequence filtered = super.filter(source, start, end, dest, dstart, dend);
                 if (filtered == null) {
@@ -1981,6 +1882,27 @@
     }
 
     /**
+     * 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.
+     */
+    private boolean ensureScrollWheelAdjusted() {
+        // 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;
+    }
+
+    /**
      * Command for setting the input text selection.
      */
     class SetSelectionCommand implements Runnable {
@@ -1994,39 +1916,18 @@
     }
 
     /**
-     * Command for adjusting the scroller to show in its center the closest of
-     * the displayed items.
-     */
-    class AdjustScrollerCommand implements Runnable {
-        public void run() {
-            mPreviousScrollerY = 0;
-            if (mInitialScrollOffset == mCurrentScrollOffset) {
-                updateInputTextView();
-                showInputControls(mShowInputControlsAnimimationDuration);
-                return;
-            }
-            // adjust to the closest value
-            int deltaY = mInitialScrollOffset - mCurrentScrollOffset;
-            if (Math.abs(deltaY) > mSelectorElementHeight / 2) {
-                deltaY += (deltaY > 0) ? -mSelectorElementHeight : mSelectorElementHeight;
-            }
-            mAdjustScroller.startScroll(0, 0, 0, deltaY, SELECTOR_ADJUSTMENT_DURATION_MILLIS);
-            invalidate();
-        }
-    }
-
-    /**
      * Command for changing the current value from a long press by one.
      */
     class ChangeCurrentByOneFromLongPressCommand implements Runnable {
         private boolean mIncrement;
 
-        private void setIncrement(boolean increment) {
+        private void setStep(boolean increment) {
             mIncrement = increment;
         }
 
+        @Override
         public void run() {
-            changeCurrentByOne(mIncrement);
+            changeValueByOne(mIncrement);
             postDelayed(this, mLongPressUpdateInterval);
         }
     }
@@ -2048,4 +1949,248 @@
             }
         }
     }
+
+    /**
+     * Command for beginning soft input on long press.
+     */
+    class BeginSoftInputOnLongPressCommand implements Runnable {
+
+        @Override
+        public void run() {
+            showSoftInput();
+            mIngonreMoveEvents = true;
+        }
+    }
+
+    class AccessibilityNodeProviderImpl extends AccessibilityNodeProvider {
+        private static final int VIRTUAL_VIEW_ID_INCREMENT = 1;
+
+        private static final int VIRTUAL_VIEW_ID_INPUT = 2;
+
+        private static final int VIRTUAL_VIEW_ID_DECREMENT = 3;
+
+        private final Rect mTempRect = new Rect();
+
+        private final int[] mTempArray = new int[2];
+
+        @Override
+        public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
+            switch (virtualViewId) {
+                case View.NO_ID:
+                    return createAccessibilityNodeInfoForNumberPicker( mScrollX, mScrollY,
+                            mScrollX + (mRight - mLeft), mScrollY + (mBottom - mTop));
+                case VIRTUAL_VIEW_ID_DECREMENT:
+                    return createAccessibilityNodeInfoForVirtualButton(VIRTUAL_VIEW_ID_DECREMENT,
+                            getVirtualDecrementButtonText(), mScrollX, mScrollY,
+                            mScrollX + (mRight - mLeft),
+                            mTopSelectionDividerTop + mSelectionDividerHeight);
+                case VIRTUAL_VIEW_ID_INPUT:
+                    return createAccessibiltyNodeInfoForInputText();
+                case VIRTUAL_VIEW_ID_INCREMENT:
+                    return createAccessibilityNodeInfoForVirtualButton(VIRTUAL_VIEW_ID_INCREMENT,
+                            getVirtualIncrementButtonText(), mScrollX,
+                            mBottomSelectionDividerBottom - mSelectionDividerHeight,
+                            mScrollX + (mRight - mLeft), mScrollY + (mBottom - mTop));
+            }
+            return super.createAccessibilityNodeInfo(virtualViewId);
+        }
+
+        @Override
+        public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String searched,
+                int virtualViewId) {
+            if (TextUtils.isEmpty(searched)) {
+                return Collections.emptyList();
+            }
+            String searchedLowerCase = searched.toLowerCase();
+            List<AccessibilityNodeInfo> result = new ArrayList<AccessibilityNodeInfo>();
+            switch (virtualViewId) {
+                case View.NO_ID: {
+                    findAccessibilityNodeInfosByTextInChild(searchedLowerCase,
+                            VIRTUAL_VIEW_ID_DECREMENT, result);
+                    findAccessibilityNodeInfosByTextInChild(searchedLowerCase,
+                            VIRTUAL_VIEW_ID_INPUT, result);
+                    findAccessibilityNodeInfosByTextInChild(searchedLowerCase,
+                            VIRTUAL_VIEW_ID_INCREMENT, result);
+                    return result;
+                }
+                case VIRTUAL_VIEW_ID_DECREMENT:
+                case VIRTUAL_VIEW_ID_INCREMENT:
+                case VIRTUAL_VIEW_ID_INPUT: {
+                    findAccessibilityNodeInfosByTextInChild(searchedLowerCase, virtualViewId,
+                            result);
+                    return result;
+                }
+            }
+            return super.findAccessibilityNodeInfosByText(searched, virtualViewId);
+        }
+
+        @Override
+        public boolean performAccessibilityAction(int action, int virtualViewId) {
+            switch (virtualViewId) {
+                case VIRTUAL_VIEW_ID_INPUT: {
+                    switch (action) {
+                        case AccessibilityNodeInfo.ACTION_FOCUS: {
+                            if (!mInputText.isFocused()) {
+                                return mInputText.requestFocus();
+                            }
+                        } break;
+                        case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: {
+                            if (mInputText.isFocused()) {
+                                mInputText.clearFocus();
+                                return true;
+                            }
+                        } break;
+                    }
+                } break;
+            }
+            return super.performAccessibilityAction(action, virtualViewId);
+        }
+
+        public void sendAccessibilityEventForVirtualView(int virtualViewId, int eventType) {
+            switch (virtualViewId) {
+                case VIRTUAL_VIEW_ID_DECREMENT: {
+                    sendAccessibilityEventForVirtualButton(virtualViewId, eventType,
+                            getVirtualDecrementButtonText());
+                } break;
+                case VIRTUAL_VIEW_ID_INPUT: {
+                    sendAccessibilityEventForVirtualText(eventType);
+                } break;
+                case VIRTUAL_VIEW_ID_INCREMENT: {
+                    sendAccessibilityEventForVirtualButton(virtualViewId, eventType,
+                            getVirtualIncrementButtonText());
+                } break;
+            }
+        }
+
+        private void sendAccessibilityEventForVirtualText(int eventType) {
+            AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
+            mInputText.onInitializeAccessibilityEvent(event);
+            mInputText.onPopulateAccessibilityEvent(event);
+            event.setSource(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT);
+            requestSendAccessibilityEvent(NumberPicker.this, event);
+        }
+
+        private void sendAccessibilityEventForVirtualButton(int virtualViewId, int eventType,
+                String text) {
+            AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
+            event.setClassName(Button.class.getName());
+            event.setPackageName(mContext.getPackageName());
+            event.getText().add(text);
+            event.setEnabled(NumberPicker.this.isEnabled());
+            event.setSource(NumberPicker.this, virtualViewId);
+            requestSendAccessibilityEvent(NumberPicker.this, event);
+        }
+
+        private void findAccessibilityNodeInfosByTextInChild(String searchedLowerCase,
+                int virtualViewId, List<AccessibilityNodeInfo> outResult) {
+            switch (virtualViewId) {
+                case VIRTUAL_VIEW_ID_DECREMENT: {
+                    String text = getVirtualDecrementButtonText();
+                    if (!TextUtils.isEmpty(text)
+                            && text.toString().toLowerCase().contains(searchedLowerCase)) {
+                        outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_DECREMENT));
+                    }
+                } return;
+                case VIRTUAL_VIEW_ID_INPUT: {
+                    CharSequence text = mInputText.getText();
+                    if (!TextUtils.isEmpty(text) &&
+                            text.toString().toLowerCase().contains(searchedLowerCase)) {
+                        outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INPUT));
+                        return;
+                    }
+                    CharSequence contentDesc = mInputText.getText();
+                    if (!TextUtils.isEmpty(contentDesc) &&
+                            contentDesc.toString().toLowerCase().contains(searchedLowerCase)) {
+                        outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INPUT));
+                        return;
+                    }
+                } break;
+                case VIRTUAL_VIEW_ID_INCREMENT: {
+                    String text = getVirtualIncrementButtonText();
+                    if (!TextUtils.isEmpty(text)
+                            && text.toString().toLowerCase().contains(searchedLowerCase)) {
+                        outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INCREMENT));
+                    }
+                } return;
+            }
+        }
+
+        private AccessibilityNodeInfo createAccessibiltyNodeInfoForInputText() {
+            AccessibilityNodeInfo info = mInputText.createAccessibilityNodeInfo();
+            info.setLongClickable(true);
+            info.setSource(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT);
+            return info;
+        }
+
+        private AccessibilityNodeInfo createAccessibilityNodeInfoForVirtualButton(int virtualViewId,
+                String text, int left, int top, int right, int bottom) {
+            AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+            info.setClassName(Button.class.getName());
+            info.setPackageName(mContext.getPackageName());
+            info.setSource(NumberPicker.this, virtualViewId);
+            info.setParent(NumberPicker.this);
+            info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_DECREMENT);
+            info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT);
+            info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INCREMENT);
+            info.setText(text);
+            info.setClickable(true);
+            info.setLongClickable(true);
+            info.setEnabled(NumberPicker.this.isEnabled());
+            Rect boundsInParent = mTempRect;
+            boundsInParent.set(left, top, right, bottom);
+            info.setBoundsInParent(boundsInParent);
+            Rect boundsInScreen = boundsInParent;
+            int[] locationOnScreen = mTempArray;
+            getLocationOnScreen(locationOnScreen);
+            boundsInScreen.offsetTo(0, 0);
+            boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]);
+            info.setBoundsInScreen(boundsInScreen);
+            return info;
+        }
+
+        private AccessibilityNodeInfo createAccessibilityNodeInfoForNumberPicker(int left, int top,
+                int right, int bottom) {
+            AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+            info.setClassName(Button.class.getName());
+            info.setPackageName(mContext.getPackageName());
+            info.setSource(NumberPicker.this);
+            info.setParent((View) getParent());
+            info.setEnabled(NumberPicker.this.isEnabled());
+            info.setScrollable(true);
+            Rect boundsInParent = mTempRect;
+            boundsInParent.set(left, top, right, bottom);
+            info.setBoundsInParent(boundsInParent);
+            Rect boundsInScreen = boundsInParent;
+            int[] locationOnScreen = mTempArray;
+            getLocationOnScreen(locationOnScreen);
+            boundsInScreen.offsetTo(0, 0);
+            boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]);
+            info.setBoundsInScreen(boundsInScreen);
+            return info;
+        }
+
+        private String getVirtualDecrementButtonText() {
+            int value = mValue - 1;
+            if (mWrapSelectorWheel) {
+                value = getWrappedSelectorIndex(value);
+            }
+            if (value >= mMinValue) {
+                return (mDisplayedValues == null) ? formatNumber(value)
+                        : mDisplayedValues[value - mMinValue];
+            }
+            return null;
+        }
+
+        private String getVirtualIncrementButtonText() {
+            int value = mValue + 1;
+            if (mWrapSelectorWheel) {
+                value = getWrappedSelectorIndex(value);
+            }
+            if (value <= mMaxValue) {
+                return (mDisplayedValues == null) ? formatNumber(value)
+                        : mDisplayedValues[value - mMinValue];
+            }
+            return null;
+        }
+    }
 }
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 7eff1aa..bc88b62 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -532,21 +532,28 @@
 
     private void setContentDescriptions() {
         // Minute
-        String text = mContext.getString(R.string.time_picker_increment_minute_button);
-        mMinuteSpinner.findViewById(R.id.increment).setContentDescription(text);
-        text = mContext.getString(R.string.time_picker_decrement_minute_button);
-        mMinuteSpinner.findViewById(R.id.decrement).setContentDescription(text);
+        trySetContentDescription(mMinuteSpinner, R.id.increment,
+                R.string.time_picker_increment_minute_button);
+        trySetContentDescription(mMinuteSpinner, R.id.decrement,
+                R.string.time_picker_decrement_minute_button);
         // Hour
-        text = mContext.getString(R.string.time_picker_increment_hour_button);
-        mHourSpinner.findViewById(R.id.increment).setContentDescription(text);
-        text = mContext.getString(R.string.time_picker_decrement_hour_button);
-        mHourSpinner.findViewById(R.id.decrement).setContentDescription(text);
+        trySetContentDescription(mHourSpinner, R.id.increment,
+                R.string.time_picker_increment_hour_button);
+        trySetContentDescription(mHourSpinner, R.id.decrement,
+                R.string.time_picker_decrement_hour_button);
         // AM/PM
         if (mAmPmSpinner != null) {
-            text = mContext.getString(R.string.time_picker_increment_set_pm_button);
-            mAmPmSpinner.findViewById(R.id.increment).setContentDescription(text);
-            text = mContext.getString(R.string.time_picker_decrement_set_am_button);
-            mAmPmSpinner.findViewById(R.id.decrement).setContentDescription(text);
+            trySetContentDescription(mAmPmSpinner, R.id.increment,
+                    R.string.time_picker_increment_set_pm_button);
+            trySetContentDescription(mAmPmSpinner, R.id.decrement,
+                    R.string.time_picker_decrement_set_am_button);
+        }
+    }
+
+    private void trySetContentDescription(View root, int viewId, int contDescResId) {
+        View target = root.findViewById(viewId);
+        if (target != null) {
+            target.setContentDescription(mContext.getString(contDescResId));
         }
     }
 
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_dark.png
deleted file mode 100644
index 9584649..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_light.png
deleted file mode 100644
index 5c37873..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_dark.png
deleted file mode 100644
index b5faf6f..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_light.png
deleted file mode 100644
index 041412b..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png
deleted file mode 100644
index 5717bee..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png
deleted file mode 100644
index e874330..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png
deleted file mode 100644
index 96a6c8a..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png
deleted file mode 100644
index 96a6c8a..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png
deleted file mode 100644
index 4631d85..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png
deleted file mode 100644
index 39c7af4..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_dark.png
deleted file mode 100644
index 9c23a18..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_light.png
deleted file mode 100644
index 9c23a18..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_dark.png
deleted file mode 100644
index 159913c..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_light.png
deleted file mode 100644
index cfee4b7..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_dark.png
deleted file mode 100644
index e5f0430..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_light.png
deleted file mode 100644
index 7e4ec4a..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png
deleted file mode 100644
index b06017e..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png
deleted file mode 100644
index a1000f8..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png
deleted file mode 100644
index b3d6706..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png
deleted file mode 100644
index b3d6706..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png
deleted file mode 100644
index 9ee35c7..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png
deleted file mode 100644
index 4da4fa7..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_dark.png
deleted file mode 100644
index 358a13f..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_light.png
deleted file mode 100644
index 358a13f..0000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png
deleted file mode 100644
index 50f6e98..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png
deleted file mode 100644
index 67434f6..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_dark.png
deleted file mode 100644
index 9c2b833..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_light.png
deleted file mode 100644
index dcf2fb7..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_dark.png
deleted file mode 100644
index b63c510d..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_light.png
deleted file mode 100644
index 55312a1..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_dark.png
deleted file mode 100644
index 48e300c..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_light.png
deleted file mode 100644
index 48e300c..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_dark.png
deleted file mode 100644
index 1558d3d..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_light.png
deleted file mode 100644
index 6b6e7e1..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png
deleted file mode 100644
index eb16f8d..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png
deleted file mode 100644
index eb16f8d..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png
deleted file mode 100644
index 58a3b64..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png
deleted file mode 100644
index 382943b..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_dark.png
deleted file mode 100644
index cf856a1..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_light.png
deleted file mode 100644
index 6665953..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_dark.png
deleted file mode 100644
index d63d797..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_light.png
deleted file mode 100644
index 22b6dbd..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_dark.png
deleted file mode 100644
index 4bcce98..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_light.png
deleted file mode 100644
index 4bcce98..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_dark.png
deleted file mode 100644
index 12ba823..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_light.png
deleted file mode 100644
index d841f5a..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png
deleted file mode 100644
index bc5e3fa..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png
deleted file mode 100644
index bc5e3fa..0000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_dark.png
deleted file mode 100644
index 111f57e..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_light.png
deleted file mode 100644
index d0ef05b..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_dark.png
deleted file mode 100644
index ff21941..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_light.png
deleted file mode 100644
index 3e9bdda..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_dark.png
deleted file mode 100644
index 0462fca..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_light.png
deleted file mode 100644
index a488e8e..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_dark.png
deleted file mode 100644
index f61b076..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_light.png
deleted file mode 100644
index f61b076..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_dark.png
deleted file mode 100644
index 211944e..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_light.png
deleted file mode 100644
index 12bc11a..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_dark.png
deleted file mode 100644
index 635184c..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_light.png
deleted file mode 100644
index 635184c..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_dark.png
deleted file mode 100644
index 470e569..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_light.png
deleted file mode 100644
index 16df74d..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_dark.png
deleted file mode 100644
index edd4c04..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_light.png
deleted file mode 100644
index d8f459a..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_dark.png
deleted file mode 100644
index 08bf241..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_light.png
deleted file mode 100644
index b2c40f1..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_dark.png
deleted file mode 100644
index f4f7331..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_light.png
deleted file mode 100644
index f4f7331..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_dark.png
deleted file mode 100644
index 83650b1..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_light.png
deleted file mode 100644
index 78085d3..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_dark.png
deleted file mode 100644
index b8f6849..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_light.png
deleted file mode 100644
index b8f6849..0000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/numberpicker_down_btn_holo_dark.xml b/core/res/res/drawable/numberpicker_down_btn_holo_dark.xml
deleted file mode 100644
index dd6332d..0000000
--- a/core/res/res/drawable/numberpicker_down_btn_holo_dark.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:state_pressed="false"
-          android:state_enabled="true"
-          android:state_focused="false"
-          android:drawable="@drawable/numberpicker_down_normal_holo_dark" />
-
-    <item android:state_pressed="true"
-          android:state_enabled="true"
-          android:drawable="@drawable/numberpicker_down_pressed_holo_dark" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="true"
-          android:state_focused="true"
-          android:drawable="@drawable/numberpicker_down_focused_holo_dark" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="false"
-          android:state_focused="false"
-          android:drawable="@drawable/numberpicker_down_disabled_holo_dark" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="false"
-          android:state_focused="true"
-          android:drawable="@drawable/numberpicker_down_disabled_focused_holo_dark" />
-
-</selector>
diff --git a/core/res/res/drawable/numberpicker_down_btn_holo_light.xml b/core/res/res/drawable/numberpicker_down_btn_holo_light.xml
deleted file mode 100644
index 565fd86..0000000
--- a/core/res/res/drawable/numberpicker_down_btn_holo_light.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:state_pressed="false"
-          android:state_enabled="true"
-          android:state_focused="false"
-          android:drawable="@drawable/numberpicker_down_normal_holo_light" />
-
-    <item android:state_pressed="true"
-          android:state_enabled="true"
-          android:drawable="@drawable/numberpicker_down_pressed_holo_light" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="true"
-          android:state_focused="true"
-          android:drawable="@drawable/numberpicker_down_focused_holo_light" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="false"
-          android:state_focused="false"
-          android:drawable="@drawable/numberpicker_down_disabled_holo_light" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="false"
-          android:state_focused="true"
-          android:drawable="@drawable/numberpicker_down_disabled_focused_holo_light" />
-
-</selector>
diff --git a/core/res/res/drawable/numberpicker_up_btn_holo_dark.xml b/core/res/res/drawable/numberpicker_up_btn_holo_dark.xml
deleted file mode 100644
index 7af3ee4..0000000
--- a/core/res/res/drawable/numberpicker_up_btn_holo_dark.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:state_pressed="false"
-          android:state_enabled="true"
-          android:state_focused="false"
-          android:drawable="@drawable/numberpicker_up_normal_holo_dark" />
-
-    <item android:state_pressed="true"
-          android:state_enabled="true"
-          android:drawable="@drawable/numberpicker_up_pressed_holo_dark" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="true"
-          android:state_focused="true"
-          android:drawable="@drawable/numberpicker_up_focused_holo_dark" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="false"
-          android:state_focused="false"
-          android:drawable="@drawable/numberpicker_up_disabled_holo_dark" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="false"
-          android:state_focused="true"
-          android:drawable="@drawable/numberpicker_up_disabled_focused_holo_dark" />
-
-</selector>
diff --git a/core/res/res/drawable/numberpicker_up_btn_holo_light.xml b/core/res/res/drawable/numberpicker_up_btn_holo_light.xml
deleted file mode 100644
index cbcbb07..0000000
--- a/core/res/res/drawable/numberpicker_up_btn_holo_light.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:state_pressed="false"
-          android:state_enabled="true"
-          android:state_focused="false"
-          android:drawable="@drawable/numberpicker_up_normal_holo_light" />
-
-    <item android:state_pressed="true"
-          android:state_enabled="true"
-          android:drawable="@drawable/numberpicker_up_pressed_holo_light" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="true"
-          android:state_focused="true"
-          android:drawable="@drawable/numberpicker_up_focused_holo_light" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="false"
-          android:state_focused="false"
-          android:drawable="@drawable/numberpicker_up_focused_holo_light" />
-
-    <item android:state_pressed="false"
-          android:state_enabled="false"
-          android:state_focused="true"
-          android:drawable="@drawable/numberpicker_up_disabled_focused_holo_light" />
-
-</selector>
diff --git a/core/res/res/layout/number_picker.xml b/core/res/res/layout/number_picker.xml
index 2967696..b7e7ae1 100644
--- a/core/res/res/layout/number_picker.xml
+++ b/core/res/res/layout/number_picker.xml
@@ -22,19 +22,26 @@
     <ImageButton android:id="@+id/increment"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        style="?android:attr/numberPickerUpButtonStyle"
+        android:background="@android:drawable/numberpicker_up_btn"
+        android:paddingTop="22dip"
+        android:paddingBottom="22dip"
         android:contentDescription="@string/number_picker_increment_button" />
 
-    <view class="android.widget.NumberPicker$CustomEditText"
+    <EditText
         android:id="@+id/numberpicker_input"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        style="?android:attr/numberPickerInputTextStyle" />
+        android:textAppearance="@style/TextAppearance.Large.Inverse.NumberPickerInputText"
+        android:gravity="center"
+        android:singleLine="true"
+        android:background="@drawable/numberpicker_input" />
 
     <ImageButton android:id="@+id/decrement"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        style="?android:attr/numberPickerDownButtonStyle"
+        android:background="@android:drawable/numberpicker_down_btn"
+        android:paddingTop="22dip"
+        android:paddingBottom="22dip"
         android:contentDescription="@string/number_picker_decrement_button" />
 
 </merge>
diff --git a/core/res/res/layout/number_picker_with_selector_wheel.xml b/core/res/res/layout/number_picker_with_selector_wheel.xml
new file mode 100644
index 0000000..c8fa0f7
--- /dev/null
+++ b/core/res/res/layout/number_picker_with_selector_wheel.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <view class="android.widget.NumberPicker$CustomEditText"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:id="@+id/numberpicker_input"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:singleLine="true"
+        android:background="@null" />
+
+</merge>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index db908ca..428790f 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -589,12 +589,6 @@
 
         <!-- NumberPicker style. -->
         <attr name="numberPickerStyle" format="reference" />
-        <!-- NumberPicker up button style. -->
-        <attr name="numberPickerUpButtonStyle" format="reference" />
-        <!-- NumberPicker down button style. -->
-        <attr name="numberPickerDownButtonStyle" format="reference" />
-        <!-- NumberPicker input text style. -->
-        <attr name="numberPickerInputTextStyle" format="reference" />
 
         <!-- The CalendarView style. -->
         <attr name="calendarViewStyle" format="reference" />
@@ -3617,12 +3611,12 @@
     <declare-styleable name="NumberPicker">
         <!-- @hide Color for the solid color background if such for optimized rendering. -->
         <attr name="solidColor" format="color|reference" />
-        <!-- @hide Whether the number picker supports fligning. -->
-        <attr name="flingable" format="boolean" />
         <!-- @hide The divider for making the selection area. -->
         <attr name="selectionDivider" format="reference" />
         <!-- @hide The height of the selection divider. -->
         <attr name="selectionDividerHeight" format="dimension" />
+        <!-- @hide The distance between the two selection dividers. -->
+        <attr name="selectionDividersDistance" format="dimension" />
         <!-- @hide The min height of the NumberPicker. -->
         <attr name="internalMinHeight" format="dimension" />
         <!-- @hide The max height of the NumberPicker. -->
@@ -3631,6 +3625,10 @@
         <attr name="internalMinWidth" format="dimension" />
         <!-- @hide The max width of the NumberPicker. -->
         <attr name="internalMaxWidth" format="dimension" />
+        <!-- @hide The layout of the number picker. -->
+        <attr name="internalLayout" />
+        <!-- @hide The minimal move distance of a swipe to be considered a fling. -->
+       <attr name="minFlingDistance" format="dimension" />
     </declare-styleable>
 
     <declare-styleable name="TimePicker">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7799f74..f6125f00 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3190,8 +3190,6 @@
     <string name="number_picker_increment_button">Increment</string>
     <!-- Description of the button to decrement the NumberPicker value. [CHAR LIMIT=NONE] -->
     <string name="number_picker_decrement_button">Decrement</string>
-    <!-- Description of the tap and hold action to get into scroll mode in NumberPicker. [CHAR LIMIT=NONE] -->
-    <string name="number_picker_increment_scroll_mode"><xliff:g id="value" example="3">%s</xliff:g> touch and hold.</string>
     <!-- Description of the scrolling action in NumberPicker. [CHAR LIMIT=NONE] -->
     <string name="number_picker_increment_scroll_action">Slide up to increment and down to decrement.</string>
 
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index a51f3f9..288b8b2 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -521,10 +521,10 @@
     </style>
 
     <style name="Widget.NumberPicker">
+        <item name="android:internalLayout">@android:layout/number_picker</item>
         <item name="android:orientation">vertical</item>
         <item name="android:fadingEdge">vertical</item>
         <item name="android:fadingEdgeLength">50dip</item>
-        <item name="android:flingable">false</item>
     </style>
 
     <style name="Widget.TimePicker">
@@ -536,25 +536,6 @@
         <item name="android:calendarViewShown">false</item>
     </style>
 
-    <style name="Widget.ImageButton.NumberPickerUpButton">
-        <item name="android:background">@android:drawable/numberpicker_up_btn</item>
-        <item name="android:paddingTop">22dip</item>
-        <item name="android:paddingBottom">22dip</item>
-    </style>
-
-    <style name="Widget.ImageButton.NumberPickerDownButton">
-        <item name="android:background">@android:drawable/numberpicker_down_btn</item>
-        <item name="android:paddingTop">22dip</item>
-        <item name="android:paddingBottom">22dip</item>
-    </style>
-
-    <style name="Widget.EditText.NumberPickerInputText">
-        <item name="android:textAppearance">@style/TextAppearance.Large.Inverse.NumberPickerInputText</item>
-        <item name="android:gravity">center</item>
-        <item name="android:singleLine">true</item>
-        <item name="android:background">@drawable/numberpicker_input</item>
-    </style>
-
     <style name="Widget.AutoCompleteTextView" parent="Widget.EditText">
         <item name="android:completionHintView">@android:layout/simple_dropdown_hint</item>
         <item name="android:completionThreshold">2</item>
@@ -1656,12 +1637,14 @@
     </style>
 
     <style name="Widget.Holo.NumberPicker" parent="Widget.NumberPicker">
+        <item name="android:internalLayout">@android:layout/number_picker_with_selector_wheel</item>
         <item name="android:solidColor">@android:color/transparent</item>
-        <item name="android:flingable">true</item>
         <item name="android:selectionDivider">@android:drawable/numberpicker_selection_divider</item>
         <item name="android:selectionDividerHeight">2dip</item>
+        <item name="android:selectionDividersDistance">48dip</item>
         <item name="android:internalMinWidth">48dip</item>
         <item name="android:internalMaxHeight">200dip</item>
+        <item name="android:minFlingDistance">150dip</item>
     </style>
 
     <style name="Widget.Holo.TimePicker" parent="Widget.TimePicker">
@@ -1673,31 +1656,6 @@
         <item name="android:calendarViewShown">true</item>
     </style>
 
-    <style name="Widget.Holo.ImageButton.NumberPickerUpButton">
-        <item name="android:background">@null</item>
-        <item name="android:src">@android:drawable/numberpicker_up_btn_holo_dark</item>
-        <item name="android:paddingTop">16dip</item>
-        <item name="android:paddingBottom">22dip</item>
-    </style>
-
-    <style name="Widget.Holo.ImageButton.NumberPickerDownButton">
-        <item name="android:background">@null</item>
-        <item name="android:src">@android:drawable/numberpicker_down_btn_holo_dark</item>
-        <item name="android:paddingTop">22dip</item>
-        <item name="android:paddingBottom">16dip</item>
-    </style>
-
-    <style name="Widget.Holo.EditText.NumberPickerInputText">
-        <item name="android:paddingTop">13sp</item>
-        <item name="android:paddingBottom">13sp</item>
-        <item name="android:paddingLeft">2sp</item>
-        <item name="android:paddingRight">2sp</item>
-        <item name="android:gravity">center</item>
-        <item name="android:singleLine">true</item>
-        <item name="android:textSize">18sp</item>
-        <item name="android:background">@null</item>
-    </style>
-
     <style name="Widget.Holo.ActivityChooserView" parent="Widget.ActivityChooserView">
     </style>
 
@@ -2109,17 +2067,6 @@
     <style name="Widget.Holo.Light.DatePicker" parent="Widget.Holo.DatePicker">
     </style>
 
-    <style name="Widget.Holo.Light.ImageButton.NumberPickerUpButton" parent="Widget.Holo.ImageButton.NumberPickerUpButton">
-        <item name="android:src">@android:drawable/numberpicker_up_btn_holo_light</item>
-    </style>
-
-    <style name="Widget.Holo.Light.ImageButton.NumberPickerDownButton" parent="Widget.Holo.ImageButton.NumberPickerDownButton">
-        <item name="android:src">@android:drawable/numberpicker_down_btn_holo_light</item>
-    </style>
-
-    <style name="Widget.Holo.Light.EditText.NumberPickerInputText" parent="Widget.Holo.EditText.NumberPickerInputText">
-    </style>
-
     <style name="Widget.Holo.Light.ActivityChooserView" parent="Widget.Holo.ActivityChooserView">
         <item name="android:background">@android:drawable/ab_share_pack_holo_light</item>
     </style>
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index 6419872..330e68c 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -200,9 +200,6 @@
     <style name="Widget.DeviceDefault.CompoundButton.Switch" parent="Widget.Holo.CompoundButton.Switch">
 
     </style>
-    <style name="Widget.DeviceDefault.EditText.NumberPickerInputText" parent="Widget.Holo.EditText.NumberPickerInputText">
-
-    </style>
     <style name="Widget.DeviceDefault.ExpandableListView.White" parent="Widget.Holo.ExpandableListView.White">
 
     </style>
@@ -212,12 +209,6 @@
     <style name="Widget.DeviceDefault.GestureOverlayView" parent="Widget.Holo.GestureOverlayView">
 
     </style>
-    <style name="Widget.DeviceDefault.ImageButton.NumberPickerDownButton" parent="Widget.Holo.ImageButton.NumberPickerDownButton">
-
-    </style>
-    <style name="Widget.DeviceDefault.ImageButton.NumberPickerUpButton" parent="Widget.Holo.ImageButton.NumberPickerUpButton">
-
-    </style>
     <style name="Widget.DeviceDefault.ImageWell" parent="Widget.Holo.ImageWell">
 
     </style>
@@ -465,9 +456,6 @@
     <style name="Widget.DeviceDefault.Light.DatePicker" parent="Widget.Holo.Light.DatePicker">
 
     </style>
-    <style name="Widget.DeviceDefault.Light.EditText.NumberPickerInputText" parent="Widget.Holo.Light.EditText.NumberPickerInputText">
-
-    </style>
     <style name="Widget.DeviceDefault.Light.ExpandableListView.White" parent="Widget.Holo.Light.ExpandableListView.White">
 
     </style>
@@ -477,12 +465,6 @@
     <style name="Widget.DeviceDefault.Light.GestureOverlayView" parent="Widget.Holo.Light.GestureOverlayView">
 
     </style>
-    <style name="Widget.DeviceDefault.Light.ImageButton.NumberPickerDownButton" parent="Widget.Holo.Light.ImageButton.NumberPickerDownButton">
-
-    </style>
-    <style name="Widget.DeviceDefault.Light.ImageButton.NumberPickerUpButton" parent="Widget.Holo.Light.ImageButton.NumberPickerUpButton">
-
-    </style>
     <style name="Widget.DeviceDefault.Light.ImageWell" parent="Widget.Holo.Light.ImageWell">
 
     </style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 55438b2..7e06e24 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -345,10 +345,7 @@
         <!-- PreferenceFrameLayout attributes -->
         <item name="preferenceFrameLayoutStyle">@android:style/Widget.PreferenceFrameLayout</item>
 
-        <!-- NumberPicker styles-->
-        <item name="numberPickerUpButtonStyle">@style/Widget.ImageButton.NumberPickerUpButton</item>
-        <item name="numberPickerDownButtonStyle">@style/Widget.ImageButton.NumberPickerDownButton</item>
-        <item name="numberPickerInputTextStyle">@style/Widget.EditText.NumberPickerInputText</item>
+        <!-- NumberPicker style-->
         <item name="numberPickerStyle">@style/Widget.NumberPicker</item>
 
         <!-- CalendarView style-->
@@ -1141,10 +1138,7 @@
         <!-- PreferenceFrameLayout attributes -->
         <item name="preferenceFrameLayoutStyle">@android:style/Widget.Holo.PreferenceFrameLayout</item>
 
-        <!-- NumberPicker styles-->
-        <item name="numberPickerUpButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerUpButton</item>
-        <item name="numberPickerDownButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerDownButton</item>
-        <item name="numberPickerInputTextStyle">@style/Widget.Holo.EditText.NumberPickerInputText</item>
+        <!-- NumberPicker style-->
         <item name="numberPickerStyle">@style/Widget.Holo.NumberPicker</item>
 
         <!-- CalendarView style-->
@@ -1443,10 +1437,7 @@
 
         <item name="searchDialogTheme">@style/Theme.Holo.Light.SearchBar</item>
 
-        <!-- NumberPicker attributes and styles-->
-        <item name="numberPickerUpButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerUpButton</item>
-        <item name="numberPickerDownButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerDownButton</item>
-        <item name="numberPickerInputTextStyle">@style/Widget.Holo.Light.EditText.NumberPickerInputText</item>
+        <!-- NumberPicker style-->
         <item name="numberPickerStyle">@style/Widget.Holo.Light.NumberPicker</item>
 
         <!-- CalendarView style-->
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 7fd981c..ae9255a 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -179,10 +179,7 @@
         <!-- PreferenceFrameLayout attributes -->
         <item name="preferenceFrameLayoutStyle">@android:style/Widget.DeviceDefault.PreferenceFrameLayout</item>
 
-        <!-- NumberPicker styles-->
-        <item name="numberPickerUpButtonStyle">@style/Widget.DeviceDefault.ImageButton.NumberPickerUpButton</item>
-        <item name="numberPickerDownButtonStyle">@style/Widget.DeviceDefault.ImageButton.NumberPickerDownButton</item>
-        <item name="numberPickerInputTextStyle">@style/Widget.DeviceDefault.EditText.NumberPickerInputText</item>
+        <!-- NumberPicker style-->
         <item name="numberPickerStyle">@style/Widget.DeviceDefault.NumberPicker</item>
 
         <!-- CalendarView style-->
@@ -329,10 +326,7 @@
 
         <item name="searchDialogTheme">@style/Theme.DeviceDefault.Light.SearchBar</item>
 
-        <!-- NumberPicker attributes and styles-->
-        <item name="numberPickerUpButtonStyle">@style/Widget.DeviceDefault.Light.ImageButton.NumberPickerUpButton</item>
-        <item name="numberPickerDownButtonStyle">@style/Widget.DeviceDefault.Light.ImageButton.NumberPickerDownButton</item>
-        <item name="numberPickerInputTextStyle">@style/Widget.DeviceDefault.Light.EditText.NumberPickerInputText</item>
+        <!-- NumberPicker style -->
         <item name="numberPickerStyle">@style/Widget.DeviceDefault.Light.NumberPicker</item>
 
         <!-- CalendarView style-->