@@ -202,6 +202,16 @@ public String format(int value) {
202202 */
203203 private final EditText mInputText ;
204204
205+ /**
206+ * The max height of this widget.
207+ */
208+ private final int mMaxHeight ;
209+
210+ /**
211+ * The max width of this widget.
212+ */
213+ private final int mMaxWidth ;
214+
205215 /**
206216 * The height of the text.
207217 */
@@ -517,6 +527,8 @@ public NumberPicker(Context context, AttributeSet attrs, int defStyle) {
517527 getResources ().getDisplayMetrics ());
518528 mSelectionDividerHeight = attributesArray .getDimensionPixelSize (
519529 R .styleable .NumberPicker_selectionDividerHeight , defSelectionDividerHeight );
530+ mMaxHeight = attributesArray .getDimensionPixelSize (R .styleable .NumberPicker_maxHeight , 0 );
531+ mMaxWidth = attributesArray .getDimensionPixelSize (R .styleable .NumberPicker_maxWidth , 0 );
520532 attributesArray .recycle ();
521533
522534 mShowInputControlsAnimimationDuration = getResources ().getInteger (
@@ -665,7 +677,38 @@ public void onAnimationCancel(Animator animation) {
665677
666678 @ Override
667679 protected void onLayout (boolean changed , int left , int top , int right , int bottom ) {
668- super .onLayout (changed , left , top , right , bottom );
680+ if (mMaxHeight <= 0 && mMaxWidth <= 0 ) {
681+ super .onLayout (changed , left , top , right , bottom );
682+ } else {
683+ final int msrdWdth = getMeasuredWidth ();
684+ final int msrdHght = getMeasuredHeight ();
685+
686+ // Increment button at the top.
687+ final int inctBtnMsrdWdth = mIncrementButton .getMeasuredWidth ();
688+ final int incrBtnLeft = (msrdWdth - inctBtnMsrdWdth ) / 2 ;
689+ final int incrBtnTop = 0 ;
690+ final int incrBtnRight = incrBtnLeft + inctBtnMsrdWdth ;
691+ final int incrBtnBottom = incrBtnTop + mIncrementButton .getMeasuredHeight ();
692+ mIncrementButton .layout (incrBtnLeft , incrBtnTop , incrBtnRight , incrBtnBottom );
693+
694+ // Input text centered horizontally.
695+ final int inptTxtMsrdWdth = mInputText .getMeasuredWidth ();
696+ final int inptTxtMsrdHght = mInputText .getMeasuredHeight ();
697+ final int inptTxtLeft = (msrdWdth - inptTxtMsrdWdth ) / 2 ;
698+ final int inptTxtTop = (msrdHght - inptTxtMsrdHght ) / 2 ;
699+ final int inptTxtRight = inptTxtLeft + inptTxtMsrdWdth ;
700+ final int inptTxtBottom = inptTxtTop + inptTxtMsrdHght ;
701+ mInputText .layout (inptTxtLeft , inptTxtTop , inptTxtRight , inptTxtBottom );
702+
703+ // Decrement button at the top.
704+ final int decrBtnMsrdWdth = mIncrementButton .getMeasuredWidth ();
705+ final int decrBtnLeft = (msrdWdth - decrBtnMsrdWdth ) / 2 ;
706+ final int decrBtnTop = msrdHght - mDecrementButton .getMeasuredHeight ();
707+ final int decrBtnRight = decrBtnLeft + decrBtnMsrdWdth ;
708+ final int decrBtnBottom = msrdHght ;
709+ mDecrementButton .layout (decrBtnLeft , decrBtnTop , decrBtnRight , decrBtnBottom );
710+ }
711+
669712 if (!mScrollWheelAndFadingEdgesInitialized ) {
670713 mScrollWheelAndFadingEdgesInitialized = true ;
671714 // need to do all this when we know our size
@@ -674,6 +717,24 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
674717 }
675718 }
676719
720+ @ Override
721+ protected void onMeasure (int widthMeasureSpec , int heightMeasureSpec ) {
722+ super .onMeasure (widthMeasureSpec , heightMeasureSpec );
723+ final int measuredWidth ;
724+ if (mMaxWidth > 0 ) {
725+ measuredWidth = getMaxSize (widthMeasureSpec , mMaxWidth );
726+ } else {
727+ measuredWidth = getMeasuredWidth ();
728+ }
729+ final int measuredHeight ;
730+ if (mMaxHeight > 0 ) {
731+ measuredHeight = getMaxSize (heightMeasureSpec , mMaxHeight );
732+ } else {
733+ measuredHeight = getMeasuredHeight ();
734+ }
735+ setMeasuredDimension (measuredWidth , measuredHeight );
736+ }
737+
677738 @ Override
678739 public boolean onInterceptTouchEvent (MotionEvent event ) {
679740 if (!isEnabled () || !mFlingable ) {
@@ -700,17 +761,14 @@ public boolean onInterceptTouchEvent(MotionEvent event) {
700761 hideInputControls ();
701762 return true ;
702763 }
703- if (isEventInViewHitRect (event , mInputText )
704- || (!mIncrementButton .isShown ()
705- && isEventInViewHitRect (event , mIncrementButton ))
706- || (!mDecrementButton .isShown ()
707- && isEventInViewHitRect (event , mDecrementButton ))) {
708- mAdjustScrollerOnUpEvent = false ;
709- setSelectorWheelState (SELECTOR_WHEEL_STATE_LARGE );
710- hideInputControls ();
711- return true ;
764+ if (isEventInVisibleViewHitRect (event , mIncrementButton )
765+ || isEventInVisibleViewHitRect (event , mDecrementButton )) {
766+ return false ;
712767 }
713- break ;
768+ mAdjustScrollerOnUpEvent = false ;
769+ setSelectorWheelState (SELECTOR_WHEEL_STATE_LARGE );
770+ hideInputControls ();
771+ return true ;
714772 case MotionEvent .ACTION_MOVE :
715773 float currentMoveY = event .getY ();
716774 int deltaDownY = (int ) Math .abs (currentMoveY - mLastDownEventY );
@@ -1239,6 +1297,28 @@ public void sendAccessibilityEvent(int eventType) {
12391297 // perceive this widget as several controls rather as a whole.
12401298 }
12411299
1300+ /**
1301+ * Gets the max value for a size based on the measure spec passed by
1302+ * the parent and the max value for that size.
1303+ *
1304+ * @param measureSpec The measure spec.
1305+ * @param maxValue The max value for the size.
1306+ * @return The max size.
1307+ */
1308+ private int getMaxSize (int measureSpec , int maxValue ) {
1309+ final int mode = MeasureSpec .getMode (measureSpec );
1310+ switch (mode ) {
1311+ case MeasureSpec .EXACTLY :
1312+ return MeasureSpec .getSize (measureSpec );
1313+ case MeasureSpec .AT_MOST :
1314+ return Math .min (MeasureSpec .getSize (measureSpec ), maxValue );
1315+ case MeasureSpec .UNSPECIFIED :
1316+ return maxValue ;
1317+ default :
1318+ throw new IllegalArgumentException ();
1319+ }
1320+ }
1321+
12421322 /**
12431323 * Resets the selector indices and clear the cached
12441324 * string representation of these indices.
@@ -1335,11 +1415,14 @@ private void setSelectorPaintAlpha(int alpha) {
13351415 }
13361416
13371417 /**
1338- * @return If the <code>event</code> is in the <code>view</code>.
1418+ * @return If the <code>event</code> is in the visible <code>view</code>.
13391419 */
1340- private boolean isEventInViewHitRect (MotionEvent event , View view ) {
1341- view .getHitRect (mTempRect );
1342- return mTempRect .contains ((int ) event .getX (), (int ) event .getY ());
1420+ private boolean isEventInVisibleViewHitRect (MotionEvent event , View view ) {
1421+ if (view .getVisibility () == VISIBLE ) {
1422+ view .getHitRect (mTempRect );
1423+ return mTempRect .contains ((int ) event .getX (), (int ) event .getY ());
1424+ }
1425+ return false ;
13431426 }
13441427
13451428 /**
0 commit comments