From 67fceb226dae60ba3f393eb8e3d0ad874e469201 Mon Sep 17 00:00:00 2001 From: uni7corn Date: Fri, 16 Nov 2018 15:44:52 +0800 Subject: [PATCH 1/5] =?UTF-8?q?[optimize][=E5=BF=BD=E7=95=A5=E6=96=87?= =?UTF-8?q?=E4=BB=B6]=EF=BC=9A=E5=BF=BD=E7=95=A5.idea=20=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index c6cbe56..5f94008 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,7 @@ *.iml .gradle /local.properties -/.idea/workspace.xml -/.idea/libraries +/.idea .DS_Store /build /captures From eb548e16841b532fb4cc2ee83e7e07694132b7fb Mon Sep 17 00:00:00 2001 From: uni7corn Date: Fri, 16 Nov 2018 15:45:47 +0800 Subject: [PATCH 2/5] =?UTF-8?q?[optimize][=E5=BF=BD=E7=95=A5=E6=96=87?= =?UTF-8?q?=E4=BB=B6]=EF=BC=9A=E5=BF=BD=E7=95=A5.idea=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.name | 1 - .idea/compiler.xml | 22 --------------- .idea/copyright/profiles_settings.xml | 3 -- .idea/encodings.xml | 6 ---- .idea/gradle.xml | 18 +++--------- .idea/misc.xml | 40 ++------------------------- .idea/vcs.xml | 2 +- 7 files changed, 8 insertions(+), 84 deletions(-) delete mode 100644 .idea/.name delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/copyright/profiles_settings.xml delete mode 100644 .idea/encodings.xml diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 1c8ef0a..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -NumberPickerView \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 96cc43e..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3..0000000 --- a/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 97626ba..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 0091d57..2996d53 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -3,22 +3,12 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index fbb6828..fda4c27 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,43 +1,9 @@ - - + + - - - - - - - - - - - - - - - + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file From 2d6be10de38fcca72287f794f0c9ed7bcf8f19e3 Mon Sep 17 00:00:00 2001 From: uni7corn Date: Fri, 16 Nov 2018 15:47:37 +0800 Subject: [PATCH 3/5] =?UTF-8?q?[feature][=E8=87=AA=E5=8A=A8=E6=B5=8B?= =?UTF-8?q?=E9=87=8F]=EF=BC=9A=E8=87=AA=E5=8A=A8=E6=B5=8B=E9=87=8F?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E5=A4=A7=E5=B0=8F=EF=BC=8C=E5=BD=93=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E5=AE=BD=E5=BA=A6=E5=A4=A7=E5=B0=8F=E8=B6=85=E8=BF=87?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E5=AE=BD=E5=BA=A6=EF=BC=8C=E8=87=AA=E9=80=82?= =?UTF-8?q?=E5=BA=94=E6=8E=A7=E4=BB=B6=E6=98=BE=E7=A4=BA=EF=BC=8C=E4=BD=BF?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E8=83=BD=E5=AE=8C=E6=95=B4=E7=9A=84=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=9C=A8=E6=8E=A7=E4=BB=B6=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../library/NumberPickerView.java | 625 +++++++++--------- .../library/delagate/AutoMeasureDelegate.java | 28 + 2 files changed, 350 insertions(+), 303 deletions(-) create mode 100644 library/src/main/java/cn/carbswang/android/numberpickerview/library/delagate/AutoMeasureDelegate.java diff --git a/library/src/main/java/cn/carbswang/android/numberpickerview/library/NumberPickerView.java b/library/src/main/java/cn/carbswang/android/numberpickerview/library/NumberPickerView.java index 6dcc07f..118fd2e 100644 --- a/library/src/main/java/cn/carbswang/android/numberpickerview/library/NumberPickerView.java +++ b/library/src/main/java/cn/carbswang/android/numberpickerview/library/NumberPickerView.java @@ -18,12 +18,14 @@ import android.view.View; import android.view.ViewConfiguration; +import cn.carbswang.android.numberpickerview.library.delagate.AutoMeasureDelegate; + /** * Created by Carbs.Wang. * email : yeah0126@yeah.net * github : https://github.com/Carbs0126/NumberPickerView */ -public class NumberPickerView extends View{ +public class NumberPickerView extends View { // default text color of not selected item private static final int DEFAULT_TEXT_COLOR_NORMAL = 0XFF333333; @@ -179,16 +181,16 @@ public class NumberPickerView extends View{ private Handler mHandlerInMainThread; // compatible for NumberPicker - public interface OnValueChangeListener{ + public interface OnValueChangeListener { void onValueChange(NumberPickerView picker, int oldVal, int newVal); } - public interface OnValueChangeListenerRelativeToRaw{ + public interface OnValueChangeListenerRelativeToRaw { void onValueChangeRelativeToRaw(NumberPickerView picker, int oldPickedIndex, int newPickedIndex, String[] displayedValues); } - public interface OnValueChangeListenerInScrolling{ + public interface OnValueChangeListenerInScrolling { void onValueChangeInScrolling(NumberPickerView picker, int oldVal, int newVal); } @@ -197,6 +199,7 @@ public interface OnScrollListener { int SCROLL_STATE_IDLE = 0; int SCROLL_STATE_TOUCH_SCROLL = 1; int SCROLL_STATE_FLING = 2; + void onScrollStateChange(NumberPickerView view, int scrollState); } @@ -212,18 +215,20 @@ public NumberPickerView(Context context) { super(context); init(context); } + public NumberPickerView(Context context, AttributeSet attrs) { super(context, attrs); initAttr(context, attrs); init(context); } + public NumberPickerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initAttr(context, attrs); init(context); } - private void initAttr(Context context, AttributeSet attrs){ + private void initAttr(Context context, AttributeSet attrs) { if (attrs == null) { return; } @@ -231,76 +236,78 @@ private void initAttr(Context context, AttributeSet attrs){ int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); - if(attr == R.styleable.NumberPickerView_npv_ShowCount){ + if (attr == R.styleable.NumberPickerView_npv_ShowCount) { mShowCount = a.getInt(attr, DEFAULT_SHOW_COUNT); - }else if(attr == R.styleable.NumberPickerView_npv_DividerColor){ + } else if (attr == R.styleable.NumberPickerView_npv_DividerColor) { mDividerColor = a.getColor(attr, DEFAULT_DIVIDER_COLOR); - }else if(attr == R.styleable.NumberPickerView_npv_DividerHeight){ + } else if (attr == R.styleable.NumberPickerView_npv_DividerHeight) { mDividerHeight = a.getDimensionPixelSize(attr, DEFAULT_DIVIDER_HEIGHT); - }else if(attr == R.styleable.NumberPickerView_npv_DividerMarginLeft){ + } else if (attr == R.styleable.NumberPickerView_npv_DividerMarginLeft) { mDividerMarginL = a.getDimensionPixelSize(attr, DEFAULT_DIVIDER_MARGIN_HORIZONTAL); - }else if(attr == R.styleable.NumberPickerView_npv_DividerMarginRight){ + } else if (attr == R.styleable.NumberPickerView_npv_DividerMarginRight) { mDividerMarginR = a.getDimensionPixelSize(attr, DEFAULT_DIVIDER_MARGIN_HORIZONTAL); - }else if(attr == R.styleable.NumberPickerView_npv_TextArray){ + } else if (attr == R.styleable.NumberPickerView_npv_TextArray) { mDisplayedValues = convertCharSequenceArrayToStringArray(a.getTextArray(attr)); - }else if(attr == R.styleable.NumberPickerView_npv_TextColorNormal){ + } else if (attr == R.styleable.NumberPickerView_npv_TextColorNormal) { mTextColorNormal = a.getColor(attr, DEFAULT_TEXT_COLOR_NORMAL); - }else if(attr == R.styleable.NumberPickerView_npv_TextColorSelected){ + } else if (attr == R.styleable.NumberPickerView_npv_TextColorSelected) { mTextColorSelected = a.getColor(attr, DEFAULT_TEXT_COLOR_SELECTED); - }else if(attr == R.styleable.NumberPickerView_npv_TextColorHint){ + } else if (attr == R.styleable.NumberPickerView_npv_TextColorHint) { mTextColorHint = a.getColor(attr, DEFAULT_TEXT_COLOR_SELECTED); - }else if(attr == R.styleable.NumberPickerView_npv_TextSizeNormal){ + } else if (attr == R.styleable.NumberPickerView_npv_TextSizeNormal) { mTextSizeNormal = a.getDimensionPixelSize(attr, sp2px(context, DEFAULT_TEXT_SIZE_NORMAL_SP)); - }else if(attr == R.styleable.NumberPickerView_npv_TextSizeSelected){ + } else if (attr == R.styleable.NumberPickerView_npv_TextSizeSelected) { mTextSizeSelected = a.getDimensionPixelSize(attr, sp2px(context, DEFAULT_TEXT_SIZE_SELECTED_SP)); - }else if(attr == R.styleable.NumberPickerView_npv_TextSizeHint){ + } else if (attr == R.styleable.NumberPickerView_npv_TextSizeHint) { mTextSizeHint = a.getDimensionPixelSize(attr, sp2px(context, DEFAULT_TEXT_SIZE_HINT_SP)); - }else if(attr == R.styleable.NumberPickerView_npv_MinValue){ + } else if (attr == R.styleable.NumberPickerView_npv_MinValue) { mMinShowIndex = a.getInteger(attr, 0); - }else if(attr == R.styleable.NumberPickerView_npv_MaxValue){ + } else if (attr == R.styleable.NumberPickerView_npv_MaxValue) { mMaxShowIndex = a.getInteger(attr, 0); - }else if(attr == R.styleable.NumberPickerView_npv_WrapSelectorWheel){ + } else if (attr == R.styleable.NumberPickerView_npv_WrapSelectorWheel) { mWrapSelectorWheel = a.getBoolean(attr, DEFAULT_WRAP_SELECTOR_WHEEL); - }else if(attr == R.styleable.NumberPickerView_npv_ShowDivider){ + } else if (attr == R.styleable.NumberPickerView_npv_ShowDivider) { mShowDivider = a.getBoolean(attr, DEFAULT_SHOW_DIVIDER); - }else if(attr == R.styleable.NumberPickerView_npv_HintText){ + } else if (attr == R.styleable.NumberPickerView_npv_HintText) { mHintText = a.getString(attr); - }else if(attr == R.styleable.NumberPickerView_npv_AlternativeHint){ + } else if (attr == R.styleable.NumberPickerView_npv_AlternativeHint) { mAlterHint = a.getString(attr); - }else if(attr == R.styleable.NumberPickerView_npv_EmptyItemHint){ + } else if (attr == R.styleable.NumberPickerView_npv_EmptyItemHint) { mEmptyItemHint = a.getString(attr); - }else if(attr == R.styleable.NumberPickerView_npv_MarginStartOfHint){ + } else if (attr == R.styleable.NumberPickerView_npv_MarginStartOfHint) { mMarginStartOfHint = a.getDimensionPixelSize(attr, dp2px(context, DEFAULT_MARGIN_START_OF_HINT_DP)); - }else if(attr == R.styleable.NumberPickerView_npv_MarginEndOfHint){ + } else if (attr == R.styleable.NumberPickerView_npv_MarginEndOfHint) { mMarginEndOfHint = a.getDimensionPixelSize(attr, dp2px(context, DEFAULT_MARGIN_END_OF_HINT_DP)); - }else if(attr == R.styleable.NumberPickerView_npv_ItemPaddingVertical){ + } else if (attr == R.styleable.NumberPickerView_npv_ItemPaddingVertical) { mItemPaddingVertical = a.getDimensionPixelSize(attr, dp2px(context, DEFAULT_ITEM_PADDING_DP_V)); - }else if(attr == R.styleable.NumberPickerView_npv_ItemPaddingHorizontal){ + } else if (attr == R.styleable.NumberPickerView_npv_ItemPaddingHorizontal) { mItemPaddingHorizontal = a.getDimensionPixelSize(attr, dp2px(context, DEFAULT_ITEM_PADDING_DP_H)); - }else if(attr == R.styleable.NumberPickerView_npv_AlternativeTextArrayWithMeasureHint){ + } else if (attr == R.styleable.NumberPickerView_npv_AlternativeTextArrayWithMeasureHint) { mAlterTextArrayWithMeasureHint = a.getTextArray(attr); - }else if(attr == R.styleable.NumberPickerView_npv_AlternativeTextArrayWithoutMeasureHint){ + } else if (attr == R.styleable.NumberPickerView_npv_AlternativeTextArrayWithoutMeasureHint) { mAlterTextArrayWithoutMeasureHint = a.getTextArray(attr); - }else if(attr == R.styleable.NumberPickerView_npv_RespondChangeOnDetached){ + } else if (attr == R.styleable.NumberPickerView_npv_RespondChangeOnDetached) { mRespondChangeOnDetach = a.getBoolean(attr, DEFAULT_RESPOND_CHANGE_ON_DETACH); - }else if(attr == R.styleable.NumberPickerView_npv_RespondChangeInMainThread){ + } else if (attr == R.styleable.NumberPickerView_npv_RespondChangeInMainThread) { mRespondChangeInMainThread = a.getBoolean(attr, DEFAULT_RESPOND_CHANGE_IN_MAIN_THREAD); - }else if (attr == R.styleable.NumberPickerView_npv_TextEllipsize) { + } else if (attr == R.styleable.NumberPickerView_npv_TextEllipsize) { mTextEllipsize = a.getString(attr); } } a.recycle(); } - private void init(Context context){ + private void init(Context context) { mScroller = ScrollerCompat.create(context); mMiniVelocityFling = ViewConfiguration.get(getContext()).getScaledMinimumFlingVelocity(); mScaledTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); - if(mTextSizeNormal == 0) mTextSizeNormal = sp2px(context, DEFAULT_TEXT_SIZE_NORMAL_SP); - if(mTextSizeSelected == 0) mTextSizeSelected = sp2px(context, DEFAULT_TEXT_SIZE_SELECTED_SP); - if(mTextSizeHint == 0) mTextSizeHint = sp2px(context, DEFAULT_TEXT_SIZE_HINT_SP); - if(mMarginStartOfHint == 0) mMarginStartOfHint = dp2px(context, DEFAULT_MARGIN_START_OF_HINT_DP); - if(mMarginEndOfHint == 0) mMarginEndOfHint = dp2px(context, DEFAULT_MARGIN_END_OF_HINT_DP); + if (mTextSizeNormal == 0) mTextSizeNormal = sp2px(context, DEFAULT_TEXT_SIZE_NORMAL_SP); + if (mTextSizeSelected == 0) + mTextSizeSelected = sp2px(context, DEFAULT_TEXT_SIZE_SELECTED_SP); + if (mTextSizeHint == 0) mTextSizeHint = sp2px(context, DEFAULT_TEXT_SIZE_HINT_SP); + if (mMarginStartOfHint == 0) + mMarginStartOfHint = dp2px(context, DEFAULT_MARGIN_START_OF_HINT_DP); + if (mMarginEndOfHint == 0) mMarginEndOfHint = dp2px(context, DEFAULT_MARGIN_END_OF_HINT_DP); mPaintDivider.setColor(mDividerColor); mPaintDivider.setAntiAlias(true); @@ -316,58 +323,58 @@ private void init(Context context){ mPaintHint.setTextAlign(Align.CENTER); mPaintHint.setTextSize(mTextSizeHint); - if(mShowCount % 2 == 0){ + if (mShowCount % 2 == 0) { mShowCount++; } - if(mMinShowIndex == -1 || mMaxShowIndex == -1){ + if (mMinShowIndex == -1 || mMaxShowIndex == -1) { updateValueForInit(); } initHandler(); } - private void initHandler(){ + private void initHandler() { mHandlerThread = new HandlerThread("HandlerThread-For-Refreshing"); mHandlerThread.start(); - mHandlerInNewThread = new Handler(mHandlerThread.getLooper()){ + mHandlerInNewThread = new Handler(mHandlerThread.getLooper()) { @Override public void handleMessage(Message msg) { - switch(msg.what){ + switch (msg.what) { case HANDLER_WHAT_REFRESH: - if(!mScroller.isFinished()){ - if(mScrollState == OnScrollListener.SCROLL_STATE_IDLE){ + if (!mScroller.isFinished()) { + if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) { onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); } mHandlerInNewThread.sendMessageDelayed(getMsg(HANDLER_WHAT_REFRESH, 0, 0, msg.obj), HANDLER_INTERVAL_REFRESH); - }else{ + } else { int duration = 0; int willPickIndex; //if scroller finished(not scrolling), then adjust the position - if(mCurrDrawFirstItemY != 0){//need to adjust - if(mScrollState == OnScrollListener.SCROLL_STATE_IDLE){ + if (mCurrDrawFirstItemY != 0) {//need to adjust + if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) { onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); } - if(mCurrDrawFirstItemY < (-mItemHeight/2)){ + if (mCurrDrawFirstItemY < (-mItemHeight / 2)) { //adjust to scroll upward - duration = (int)((float)DEFAULT_INTERVAL_REVISE_DURATION * (mItemHeight + mCurrDrawFirstItemY) / mItemHeight); + duration = (int) ((float) DEFAULT_INTERVAL_REVISE_DURATION * (mItemHeight + mCurrDrawFirstItemY) / mItemHeight); mScroller.startScroll(0, mCurrDrawGlobalY, 0, mItemHeight + mCurrDrawFirstItemY, duration * 3); willPickIndex = getWillPickIndexByGlobalY(mCurrDrawGlobalY + mItemHeight + mCurrDrawFirstItemY); - }else{ + } else { //adjust to scroll downward - duration = (int)((float)DEFAULT_INTERVAL_REVISE_DURATION * (-mCurrDrawFirstItemY) / mItemHeight); + duration = (int) ((float) DEFAULT_INTERVAL_REVISE_DURATION * (-mCurrDrawFirstItemY) / mItemHeight); mScroller.startScroll(0, mCurrDrawGlobalY, 0, mCurrDrawFirstItemY, duration * 3); willPickIndex = getWillPickIndexByGlobalY(mCurrDrawGlobalY + mCurrDrawFirstItemY); } postInvalidate(); - }else{ + } else { onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); //get the index which will be selected willPickIndex = getWillPickIndexByGlobalY(mCurrDrawGlobalY); } Message changeMsg = getMsg(HANDLER_WHAT_LISTENER_VALUE_CHANGED, mPrevPickedIndex, willPickIndex, msg.obj); - if(mRespondChangeInMainThread){ + if (mRespondChangeInMainThread) { mHandlerInMainThread.sendMessageDelayed(changeMsg, duration * 2); - }else{ + } else { mHandlerInNewThread.sendMessageDelayed(changeMsg, duration * 2); } } @@ -378,17 +385,17 @@ public void handleMessage(Message msg) { } } }; - mHandlerInMainThread = new Handler(){ + mHandlerInMainThread = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); - switch (msg.what){ + switch (msg.what) { case HANDLER_WHAT_REQUEST_LAYOUT: requestLayout(); - break; + break; case HANDLER_WHAT_LISTENER_VALUE_CHANGED: respondPickedValueChanged(msg.arg1, msg.arg2, msg.obj); - break; + break; } } }; @@ -415,14 +422,14 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) { mViewWidth = w; mViewHeight = h; mItemHeight = mViewHeight / mShowCount; - mViewCenterX = ((float)(mViewWidth + getPaddingLeft() - getPaddingRight()))/2; + mViewCenterX = ((float) (mViewWidth + getPaddingLeft() - getPaddingRight())) / 2; int defaultValue = 0; - if(getOneRecycleSize() > 1){ - if(mHasInit) { + if (getOneRecycleSize() > 1) { + if (mHasInit) { defaultValue = getValue() - mMinValue; - }else if(mCurrentItemIndexEffect) { + } else if (mCurrentItemIndexEffect) { defaultValue = mCurrDrawFirstItemIndex + (mShowCount - 1) / 2; - }else{ + } else { defaultValue = 0; } } @@ -436,7 +443,7 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - if(mHandlerThread == null || !mHandlerThread.isAlive()) { + if (mHandlerThread == null || !mHandlerThread.isAlive()) { initHandler(); } } @@ -447,15 +454,15 @@ protected void onDetachedFromWindow() { mHandlerThread.quit(); //These codes are for dialog or PopupWindow which will be used for more than once. //Not an elegant solution, if you have any good idea, please let me know, thank you. - if(mItemHeight == 0) return; - if(!mScroller.isFinished()){ + if (mItemHeight == 0) return; + if (!mScroller.isFinished()) { mScroller.abortAnimation(); mCurrDrawGlobalY = mScroller.getCurrY(); calculateFirstItemParameterByGlobalY(); - if(mCurrDrawFirstItemY != 0){ - if(mCurrDrawFirstItemY < (-mItemHeight/2)){ + if (mCurrDrawFirstItemY != 0) { + if (mCurrDrawFirstItemY < (-mItemHeight / 2)) { mCurrDrawGlobalY = mCurrDrawGlobalY + mItemHeight + mCurrDrawFirstItemY; - }else{ + } else { mCurrDrawGlobalY = mCurrDrawGlobalY + mCurrDrawFirstItemY; } calculateFirstItemParameterByGlobalY(); @@ -466,7 +473,7 @@ protected void onDetachedFromWindow() { // please initialize NumberPickerView's data every time setting up NumberPickerView, // set the demo of GregorianLunarCalendar int currPickedIndex = getWillPickIndexByGlobalY(mCurrDrawGlobalY); - if(currPickedIndex != mPrevPickedIndex && mRespondChangeOnDetach){ + if (currPickedIndex != mPrevPickedIndex && mRespondChangeOnDetach) { try { if (mOnValueChangeListener != null) { mOnValueChangeListener.onValueChange(NumberPickerView.this, mPrevPickedIndex + mMinValue, currPickedIndex + mMinValue); @@ -474,29 +481,29 @@ protected void onDetachedFromWindow() { if (mOnValueChangeListenerRaw != null) { mOnValueChangeListenerRaw.onValueChangeRelativeToRaw(NumberPickerView.this, mPrevPickedIndex, currPickedIndex, mDisplayedValues); } - }catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); } } mPrevPickedIndex = currPickedIndex; } - public int getOneRecycleSize(){ + public int getOneRecycleSize() { return mMaxShowIndex - mMinShowIndex + 1; } - public int getRawContentSize(){ - if(mDisplayedValues != null) + public int getRawContentSize() { + if (mDisplayedValues != null) return mDisplayedValues.length; return 0; } - public void setDisplayedValuesAndPickedIndex(String[] newDisplayedValues, int pickedIndex, boolean needRefresh){ + public void setDisplayedValuesAndPickedIndex(String[] newDisplayedValues, int pickedIndex, boolean needRefresh) { stopScrolling(); - if(newDisplayedValues == null){ + if (newDisplayedValues == null) { throw new IllegalArgumentException("newDisplayedValues should not be null."); } - if(pickedIndex < 0){ + if (pickedIndex < 0) { throw new IllegalArgumentException("pickedIndex should not be negative, now pickedIndex is " + pickedIndex); } updateContent(newDisplayedValues); @@ -505,24 +512,24 @@ public void setDisplayedValuesAndPickedIndex(String[] newDisplayedValues, int pi updateValue(); mPrevPickedIndex = pickedIndex + mMinShowIndex; correctPositionByDefaultValue(pickedIndex, mWrapSelectorWheel && mWrapSelectorWheelCheck); - if(needRefresh){ + if (needRefresh) { mHandlerInNewThread.sendMessageDelayed(getMsg(HANDLER_WHAT_REFRESH), 0); postInvalidate(); } } - public void setDisplayedValues(String[] newDisplayedValues, boolean needRefresh){ + public void setDisplayedValues(String[] newDisplayedValues, boolean needRefresh) { setDisplayedValuesAndPickedIndex(newDisplayedValues, 0, needRefresh); } - public void setDisplayedValues(String[] newDisplayedValues){ + public void setDisplayedValues(String[] newDisplayedValues) { stopRefreshing(); stopScrolling(); - if(newDisplayedValues == null){ + if (newDisplayedValues == null) { throw new IllegalArgumentException("newDisplayedValues should not be null."); } - if(mMaxValue - mMinValue + 1 > newDisplayedValues.length){ + if (mMaxValue - mMinValue + 1 > newDisplayedValues.length) { throw new IllegalArgumentException("mMaxValue - mMinValue + 1 should not be greater than mDisplayedValues.length, now " + "((mMaxValue - mMinValue + 1) is " + (mMaxValue - mMinValue + 1) + " newDisplayedValues.length is " + newDisplayedValues.length @@ -538,21 +545,22 @@ public void setDisplayedValues(String[] newDisplayedValues){ /** * Gets the values to be displayed instead of string values. + * * @return The displayed values. */ public String[] getDisplayedValues() { return mDisplayedValues; } - public void setWrapSelectorWheel(boolean wrapSelectorWheel){ - if(mWrapSelectorWheel != wrapSelectorWheel) { - if(!wrapSelectorWheel) { - if(mScrollState == OnScrollListener.SCROLL_STATE_IDLE){ + public void setWrapSelectorWheel(boolean wrapSelectorWheel) { + if (mWrapSelectorWheel != wrapSelectorWheel) { + if (!wrapSelectorWheel) { + if (mScrollState == OnScrollListener.SCROLL_STATE_IDLE) { internalSetWrapToLinear(); - }else{ + } else { mPendingWrapToLinear = true; } - }else{ + } else { mWrapSelectorWheel = wrapSelectorWheel; updateWrapStateByContent(); postInvalidate(); @@ -564,9 +572,10 @@ public void setWrapSelectorWheel(boolean wrapSelectorWheel){ * get the "fromValue" by using getValue(), if your picker's minValue is not 0, * make sure you can get the accurate value by getValue(), or you can use * smoothScrollToValue(int fromValue, int toValue, boolean needRespond) + * * @param toValue the value you want picker to scroll to */ - public void smoothScrollToValue(int toValue){ + public void smoothScrollToValue(int toValue) { smoothScrollToValue(getValue(), toValue, true); } @@ -574,46 +583,47 @@ public void smoothScrollToValue(int toValue){ * get the "fromValue" by using getValue(), if your picker's minValue is not 0, * make sure you can get the accurate value by getValue(), or you can use * smoothScrollToValue(int fromValue, int toValue, boolean needRespond) - * @param toValue the value you want picker to scroll to + * + * @param toValue the value you want picker to scroll to * @param needRespond set if you want picker to respond onValueChange listener */ - public void smoothScrollToValue(int toValue, boolean needRespond){ + public void smoothScrollToValue(int toValue, boolean needRespond) { smoothScrollToValue(getValue(), toValue, needRespond); } - public void smoothScrollToValue(int fromValue, int toValue){ + public void smoothScrollToValue(int fromValue, int toValue) { smoothScrollToValue(fromValue, toValue, true); } /** - * - * @param fromValue need to set the fromValue, can be greater than mMaxValue or less than mMinValue - * @param toValue the value you want picker to scroll to + * @param fromValue need to set the fromValue, can be greater than mMaxValue or less than mMinValue + * @param toValue the value you want picker to scroll to * @param needRespond need Respond to the ValueChange callback When Scrolling, default is false */ - public void smoothScrollToValue(int fromValue, int toValue, boolean needRespond){ + public void smoothScrollToValue(int fromValue, int toValue, boolean needRespond) { int deltaIndex; fromValue = refineValueByLimit(fromValue, mMinValue, mMaxValue, mWrapSelectorWheel && mWrapSelectorWheelCheck); toValue = refineValueByLimit(toValue, mMinValue, mMaxValue, mWrapSelectorWheel && mWrapSelectorWheelCheck); - if(mWrapSelectorWheel && mWrapSelectorWheelCheck) { + if (mWrapSelectorWheel && mWrapSelectorWheelCheck) { deltaIndex = toValue - fromValue; int halfOneRecycleSize = getOneRecycleSize() / 2; - if(deltaIndex < -halfOneRecycleSize || halfOneRecycleSize < deltaIndex ){ + if (deltaIndex < -halfOneRecycleSize || halfOneRecycleSize < deltaIndex) { deltaIndex = deltaIndex > 0 ? deltaIndex - getOneRecycleSize() : deltaIndex + getOneRecycleSize(); } - }else{ + } else { deltaIndex = toValue - fromValue; } setValue(fromValue); - if(fromValue == toValue) return; + if (fromValue == toValue) return; scrollByIndexSmoothly(deltaIndex, needRespond); } /** * simplify the "setDisplayedValue() + setMinValue() + setMaxValue()" process, * default minValue is 0, and make sure you do NOT change the minValue. + * * @param display new values to be displayed */ public void refreshByNewDisplayedValues(String[] display) { @@ -636,102 +646,102 @@ public void refreshByNewDisplayedValues(String[] display) { /** * used by handlers to respond onchange callbacks - * @param oldVal prevPicked value - * @param newVal currPicked value + * + * @param oldVal prevPicked value + * @param newVal currPicked value * @param respondChange if want to respond onchange callbacks */ - private void respondPickedValueChanged(int oldVal, int newVal, Object respondChange){ + private void respondPickedValueChanged(int oldVal, int newVal, Object respondChange) { onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); - if(oldVal != newVal){ - if(respondChange == null || !(respondChange instanceof Boolean) || (Boolean) respondChange) { - if(mOnValueChangeListener != null) { + if (oldVal != newVal) { + if (respondChange == null || !(respondChange instanceof Boolean) || (Boolean) respondChange) { + if (mOnValueChangeListener != null) { mOnValueChangeListener.onValueChange(NumberPickerView.this, oldVal + mMinValue, newVal + mMinValue); } - if(mOnValueChangeListenerRaw != null){ + if (mOnValueChangeListenerRaw != null) { mOnValueChangeListenerRaw.onValueChangeRelativeToRaw(NumberPickerView.this, oldVal, newVal, mDisplayedValues); } } } mPrevPickedIndex = newVal; - if(mPendingWrapToLinear){ + if (mPendingWrapToLinear) { mPendingWrapToLinear = false; internalSetWrapToLinear(); } } - private void scrollByIndexSmoothly(int deltaIndex){ + private void scrollByIndexSmoothly(int deltaIndex) { scrollByIndexSmoothly(deltaIndex, true); } /** - * - * @param deltaIndex the delta index it will scroll by + * @param deltaIndex the delta index it will scroll by * @param needRespond need Respond to the ValueChange callback When Scrolling, default is false */ - private void scrollByIndexSmoothly(int deltaIndex, boolean needRespond){ - if(!(mWrapSelectorWheel && mWrapSelectorWheelCheck)){ + private void scrollByIndexSmoothly(int deltaIndex, boolean needRespond) { + if (!(mWrapSelectorWheel && mWrapSelectorWheelCheck)) { int willPickRawIndex = getPickedIndexRelativeToRaw(); - if(willPickRawIndex + deltaIndex > mMaxShowIndex){ + if (willPickRawIndex + deltaIndex > mMaxShowIndex) { deltaIndex = mMaxShowIndex - willPickRawIndex; - }else if(willPickRawIndex + deltaIndex < mMinShowIndex){ + } else if (willPickRawIndex + deltaIndex < mMinShowIndex) { deltaIndex = mMinShowIndex - willPickRawIndex; } } int duration; int dy; - if(mCurrDrawFirstItemY < (-mItemHeight/2)){ + if (mCurrDrawFirstItemY < (-mItemHeight / 2)) { //scroll upwards for a distance of less than mItemHeight - dy = mItemHeight + mCurrDrawFirstItemY; - duration = (int)((float)DEFAULT_INTERVAL_REVISE_DURATION * (mItemHeight + mCurrDrawFirstItemY) / mItemHeight); - if(deltaIndex < 0){ + dy = mItemHeight + mCurrDrawFirstItemY; + duration = (int) ((float) DEFAULT_INTERVAL_REVISE_DURATION * (mItemHeight + mCurrDrawFirstItemY) / mItemHeight); + if (deltaIndex < 0) { duration = -duration - deltaIndex * DEFAULT_INTERVAL_REVISE_DURATION; - }else{ + } else { duration = duration + deltaIndex * DEFAULT_INTERVAL_REVISE_DURATION; } - }else{ + } else { //scroll downwards for a distance of less than mItemHeight dy = mCurrDrawFirstItemY; - duration = (int)((float)DEFAULT_INTERVAL_REVISE_DURATION * (-mCurrDrawFirstItemY) / mItemHeight); - if(deltaIndex < 0){ + duration = (int) ((float) DEFAULT_INTERVAL_REVISE_DURATION * (-mCurrDrawFirstItemY) / mItemHeight); + if (deltaIndex < 0) { duration = duration - deltaIndex * DEFAULT_INTERVAL_REVISE_DURATION; - }else{ + } else { duration = duration + deltaIndex * DEFAULT_INTERVAL_REVISE_DURATION; } } dy = dy + deltaIndex * mItemHeight; - if(duration < DEFAULT_MIN_SCROLL_BY_INDEX_DURATION) + if (duration < DEFAULT_MIN_SCROLL_BY_INDEX_DURATION) duration = DEFAULT_MIN_SCROLL_BY_INDEX_DURATION; - if(duration > DEFAULT_MAX_SCROLL_BY_INDEX_DURATION) + if (duration > DEFAULT_MAX_SCROLL_BY_INDEX_DURATION) duration = DEFAULT_MAX_SCROLL_BY_INDEX_DURATION; mScroller.startScroll(0, mCurrDrawGlobalY, 0, dy, duration); - if(needRespond){ + if (needRespond) { mHandlerInNewThread.sendMessageDelayed(getMsg(HANDLER_WHAT_REFRESH), duration / 4); - }else{ + } else { mHandlerInNewThread.sendMessageDelayed(getMsg(HANDLER_WHAT_REFRESH, 0, 0, new Boolean(needRespond)), duration / 4); } postInvalidate(); } - public int getMinValue(){ + public int getMinValue() { return mMinValue; } - public int getMaxValue(){ + public int getMaxValue() { return mMaxValue; } - public void setMinValue(int minValue){ + public void setMinValue(int minValue) { mMinValue = minValue; mMinShowIndex = 0; updateNotWrapYLimit(); } //compatible for android.widget.NumberPicker - public void setMaxValue(int maxValue){ - if(mDisplayedValues == null){ + public void setMaxValue(int maxValue) { + if (mDisplayedValues == null) { throw new NullPointerException("mDisplayedValues should not be null"); } - if(maxValue - mMinValue + 1 > mDisplayedValues.length){ + if (maxValue - mMinValue + 1 > mDisplayedValues.length) { throw new IllegalArgumentException("(maxValue - mMinValue + 1) should not be greater than mDisplayedValues.length now " + " (maxValue - mMinValue + 1) is " + (maxValue - mMinValue + 1) + " and mDisplayedValues.length is " + mDisplayedValues.length); } @@ -742,78 +752,78 @@ public void setMaxValue(int maxValue){ } //compatible for android.widget.NumberPicker - public void setValue(int value){ - if(value < mMinValue){ + public void setValue(int value) { + if (value < mMinValue) { throw new IllegalArgumentException("should not set a value less than mMinValue, value is " + value); } - if(value > mMaxValue){ + if (value > mMaxValue) { throw new IllegalArgumentException("should not set a value greater than mMaxValue, value is " + value); } setPickedIndexRelativeToRaw(value - mMinValue); } //compatible for android.widget.NumberPicker - public int getValue(){ + public int getValue() { return getPickedIndexRelativeToRaw() + mMinValue; } - public String getContentByCurrValue(){ + public String getContentByCurrValue() { return mDisplayedValues[getValue() - mMinValue]; } - public boolean getWrapSelectorWheel(){ + public boolean getWrapSelectorWheel() { return mWrapSelectorWheel; } - public boolean getWrapSelectorWheelAbsolutely(){ + public boolean getWrapSelectorWheelAbsolutely() { return mWrapSelectorWheel && mWrapSelectorWheelCheck; } - public void setHintText(String hintText){ - if(isStringEqual(mHintText, hintText)) return; + public void setHintText(String hintText) { + if (isStringEqual(mHintText, hintText)) return; mHintText = hintText; mTextSizeHintCenterYOffset = getTextCenterYOffset(mPaintHint.getFontMetrics()); mWidthOfHintText = getTextWidth(mHintText, mPaintHint); mHandlerInMainThread.sendEmptyMessage(HANDLER_WHAT_REQUEST_LAYOUT); } - public void setPickedIndexRelativeToMin(int pickedIndexToMin){ - if(0 <= pickedIndexToMin && pickedIndexToMin < getOneRecycleSize()){ + public void setPickedIndexRelativeToMin(int pickedIndexToMin) { + if (0 <= pickedIndexToMin && pickedIndexToMin < getOneRecycleSize()) { mPrevPickedIndex = pickedIndexToMin + mMinShowIndex; correctPositionByDefaultValue(pickedIndexToMin, mWrapSelectorWheel && mWrapSelectorWheelCheck); postInvalidate(); } } - public void setNormalTextColor(int normalTextColor){ - if(mTextColorNormal == normalTextColor) return; + public void setNormalTextColor(int normalTextColor) { + if (mTextColorNormal == normalTextColor) return; mTextColorNormal = normalTextColor; postInvalidate(); } - public void setSelectedTextColor(int selectedTextColor){ - if(mTextColorSelected == selectedTextColor) return; + public void setSelectedTextColor(int selectedTextColor) { + if (mTextColorSelected == selectedTextColor) return; mTextColorSelected = selectedTextColor; postInvalidate(); } - public void setHintTextColor(int hintTextColor){ - if(mTextColorHint == hintTextColor) return; + public void setHintTextColor(int hintTextColor) { + if (mTextColorHint == hintTextColor) return; mTextColorHint = hintTextColor; mPaintHint.setColor(mTextColorHint); postInvalidate(); } - public void setDividerColor(int dividerColor){ - if(mDividerColor == dividerColor) return; + public void setDividerColor(int dividerColor) { + if (mDividerColor == dividerColor) return; mDividerColor = dividerColor; mPaintDivider.setColor(mDividerColor); postInvalidate(); } - public void setPickedIndexRelativeToRaw(int pickedIndexToRaw){ - if(mMinShowIndex > -1){ - if(mMinShowIndex <= pickedIndexToRaw && pickedIndexToRaw <= mMaxShowIndex){ + public void setPickedIndexRelativeToRaw(int pickedIndexToRaw) { + if (mMinShowIndex > -1) { + if (mMinShowIndex <= pickedIndexToRaw && pickedIndexToRaw <= mMaxShowIndex) { mPrevPickedIndex = pickedIndexToRaw; correctPositionByDefaultValue(pickedIndexToRaw - mMinShowIndex, mWrapSelectorWheel && mWrapSelectorWheelCheck); postInvalidate(); @@ -821,49 +831,49 @@ public void setPickedIndexRelativeToRaw(int pickedIndexToRaw){ } } - public int getPickedIndexRelativeToRaw(){ + public int getPickedIndexRelativeToRaw() { int willPickIndex; - if(mCurrDrawFirstItemY != 0){ - if(mCurrDrawFirstItemY < (-mItemHeight/2)){ + if (mCurrDrawFirstItemY != 0) { + if (mCurrDrawFirstItemY < (-mItemHeight / 2)) { willPickIndex = getWillPickIndexByGlobalY(mCurrDrawGlobalY + mItemHeight + mCurrDrawFirstItemY); - }else{ + } else { willPickIndex = getWillPickIndexByGlobalY(mCurrDrawGlobalY + mCurrDrawFirstItemY); } - }else{ + } else { willPickIndex = getWillPickIndexByGlobalY(mCurrDrawGlobalY); } return willPickIndex; } - public void setMinAndMaxShowIndex(int minShowIndex, int maxShowIndex){ + public void setMinAndMaxShowIndex(int minShowIndex, int maxShowIndex) { setMinAndMaxShowIndex(minShowIndex, maxShowIndex, true); } - public void setMinAndMaxShowIndex(int minShowIndex, int maxShowIndex, boolean needRefresh){ - if(minShowIndex > maxShowIndex){ + public void setMinAndMaxShowIndex(int minShowIndex, int maxShowIndex, boolean needRefresh) { + if (minShowIndex > maxShowIndex) { throw new IllegalArgumentException("minShowIndex should be less than maxShowIndex, minShowIndex is " + minShowIndex + ", maxShowIndex is " + maxShowIndex + "."); } - if(mDisplayedValues == null){ + if (mDisplayedValues == null) { throw new IllegalArgumentException("mDisplayedValues should not be null, you need to set mDisplayedValues first."); } else { - if(minShowIndex < 0){ + if (minShowIndex < 0) { throw new IllegalArgumentException("minShowIndex should not be less than 0, now minShowIndex is " + minShowIndex); - } else if(minShowIndex > mDisplayedValues.length - 1){ + } else if (minShowIndex > mDisplayedValues.length - 1) { throw new IllegalArgumentException("minShowIndex should not be greater than (mDisplayedValues.length - 1), now " + "(mDisplayedValues.length - 1) is " + (mDisplayedValues.length - 1) + " minShowIndex is " + minShowIndex); } - if(maxShowIndex < 0){ + if (maxShowIndex < 0) { throw new IllegalArgumentException("maxShowIndex should not be less than 0, now maxShowIndex is " + maxShowIndex); - } else if(maxShowIndex > mDisplayedValues.length - 1){ + } else if (maxShowIndex > mDisplayedValues.length - 1) { throw new IllegalArgumentException("maxShowIndex should not be greater than (mDisplayedValues.length - 1), now " + "(mDisplayedValues.length - 1) is " + (mDisplayedValues.length - 1) + " maxShowIndex is " + maxShowIndex); } } mMinShowIndex = minShowIndex; mMaxShowIndex = maxShowIndex; - if(needRefresh){ + if (needRefresh) { mPrevPickedIndex = 0 + mMinShowIndex; correctPositionByDefaultValue(0, mWrapSelectorWheel && mWrapSelectorWheelCheck); postInvalidate(); @@ -872,12 +882,13 @@ public void setMinAndMaxShowIndex(int minShowIndex, int maxShowIndex, boolean ne /** * set the friction of scroller, it will effect the scroller's acceleration when fling + * * @param friction default is ViewConfiguration.get(mContext).getScrollFriction() * if setFriction(2 * ViewConfiguration.get(mContext).getScrollFriction()), * the friction will be twice as much as before */ - public void setFriction(float friction){ - if(friction <= 0) + public void setFriction(float friction) { + if (friction <= 0) throw new IllegalArgumentException("you should set a a positive float friction, now friction is " + friction); mFriction = ViewConfiguration.get(getContext()).getScrollFriction() / friction; } @@ -894,95 +905,95 @@ private void onScrollStateChange(int scrollState) { } //compatible for NumberPicker - public void setOnScrollListener(OnScrollListener listener){ + public void setOnScrollListener(OnScrollListener listener) { mOnScrollListener = listener; } //compatible for NumberPicker - public void setOnValueChangedListener(OnValueChangeListener listener){ + public void setOnValueChangedListener(OnValueChangeListener listener) { mOnValueChangeListener = listener; } - public void setOnValueChangedListenerRelativeToRaw(OnValueChangeListenerRelativeToRaw listener){ + public void setOnValueChangedListenerRelativeToRaw(OnValueChangeListenerRelativeToRaw listener) { mOnValueChangeListenerRaw = listener; } - public void setOnValueChangeListenerInScrolling(OnValueChangeListenerInScrolling listener){ + public void setOnValueChangeListenerInScrolling(OnValueChangeListenerInScrolling listener) { mOnValueChangeListenerInScrolling = listener; } - public void setContentTextTypeface(Typeface typeface){ + public void setContentTextTypeface(Typeface typeface) { mPaintText.setTypeface(typeface); } - public void setHintTextTypeface(Typeface typeface){ + public void setHintTextTypeface(Typeface typeface) { mPaintHint.setTypeface(typeface); } //return index relative to mDisplayedValues from 0. - private int getWillPickIndexByGlobalY(int globalY){ - if(mItemHeight == 0) return 0; + private int getWillPickIndexByGlobalY(int globalY) { + if (mItemHeight == 0) return 0; int willPickIndex = globalY / mItemHeight + mShowCount / 2; int index = getIndexByRawIndex(willPickIndex, getOneRecycleSize(), mWrapSelectorWheel && mWrapSelectorWheelCheck); - if(0 <= index && index < getOneRecycleSize()){ + if (0 <= index && index < getOneRecycleSize()) { return index + mMinShowIndex; - }else{ + } else { throw new IllegalArgumentException("getWillPickIndexByGlobalY illegal index : " + index + " getOneRecycleSize() : " + getOneRecycleSize() + " mWrapSelectorWheel : " + mWrapSelectorWheel); } } - private int getIndexByRawIndex(int index, int size, boolean wrap){ - if(size <= 0) return 0; - if(wrap){ + private int getIndexByRawIndex(int index, int size, boolean wrap) { + if (size <= 0) return 0; + if (wrap) { index = index % size; - if(index < 0){ + if (index < 0) { index = index + size; } return index; - }else{ + } else { return index; } } - private void internalSetWrapToLinear(){ + private void internalSetWrapToLinear() { int rawIndex = getPickedIndexRelativeToRaw(); correctPositionByDefaultValue(rawIndex - mMinShowIndex, false); mWrapSelectorWheel = false; postInvalidate(); } - private void updateDividerAttr(){ + private void updateDividerAttr() { mDividerIndex0 = mShowCount / 2; mDividerIndex1 = mDividerIndex0 + 1; dividerY0 = mDividerIndex0 * mViewHeight / mShowCount; dividerY1 = mDividerIndex1 * mViewHeight / mShowCount; - if(mDividerMarginL < 0) mDividerMarginL = 0; - if(mDividerMarginR < 0) mDividerMarginR = 0; + if (mDividerMarginL < 0) mDividerMarginL = 0; + if (mDividerMarginR < 0) mDividerMarginR = 0; - if(mDividerMarginL + mDividerMarginR == 0) return; - if(getPaddingLeft() + mDividerMarginL >= mViewWidth - getPaddingRight() - mDividerMarginR){ + if (mDividerMarginL + mDividerMarginR == 0) return; + if (getPaddingLeft() + mDividerMarginL >= mViewWidth - getPaddingRight() - mDividerMarginR) { int surplusMargin = getPaddingLeft() + mDividerMarginL + getPaddingRight() + mDividerMarginR - mViewWidth; - mDividerMarginL = (int)(mDividerMarginL - (float)surplusMargin * mDividerMarginL/(mDividerMarginL + mDividerMarginR)); - mDividerMarginR = (int)(mDividerMarginR - (float)surplusMargin * mDividerMarginR/(mDividerMarginL + mDividerMarginR)); + mDividerMarginL = (int) (mDividerMarginL - (float) surplusMargin * mDividerMarginL / (mDividerMarginL + mDividerMarginR)); + mDividerMarginR = (int) (mDividerMarginR - (float) surplusMargin * mDividerMarginR / (mDividerMarginL + mDividerMarginR)); } } private int mNotWrapLimitYTop; private int mNotWrapLimitYBottom; - private void updateFontAttr(){ - if(mTextSizeNormal > mItemHeight) mTextSizeNormal = mItemHeight; - if(mTextSizeSelected > mItemHeight) mTextSizeSelected = mItemHeight; + private void updateFontAttr() { + if (mTextSizeNormal > mItemHeight) mTextSizeNormal = mItemHeight; + if (mTextSizeSelected > mItemHeight) mTextSizeSelected = mItemHeight; - if(mPaintHint == null){ + if (mPaintHint == null) { throw new IllegalArgumentException("mPaintHint should not be null."); } mPaintHint.setTextSize(mTextSizeHint); mTextSizeHintCenterYOffset = getTextCenterYOffset(mPaintHint.getFontMetrics()); mWidthOfHintText = getTextWidth(mHintText, mPaintHint); - if(mPaintText == null){ + if (mPaintText == null) { throw new IllegalArgumentException("mPaintText should not be null."); } mPaintText.setTextSize(mTextSizeSelected); @@ -991,33 +1002,34 @@ private void updateFontAttr(){ mTextSizeNormalCenterYOffset = getTextCenterYOffset(mPaintText.getFontMetrics()); } - private void updateNotWrapYLimit(){ + private void updateNotWrapYLimit() { mNotWrapLimitYTop = 0; mNotWrapLimitYBottom = -mShowCount * mItemHeight; - if(mDisplayedValues != null){ - mNotWrapLimitYTop = (getOneRecycleSize() - mShowCount / 2 - 1)* mItemHeight; + if (mDisplayedValues != null) { + mNotWrapLimitYTop = (getOneRecycleSize() - mShowCount / 2 - 1) * mItemHeight; mNotWrapLimitYBottom = -(mShowCount / 2) * mItemHeight; } } - private float downYGlobal = 0 ; + private float downYGlobal = 0; private float downY = 0; private float currY = 0; - private int limitY(int currDrawGlobalYPreferred){ - if(mWrapSelectorWheel && mWrapSelectorWheelCheck) return currDrawGlobalYPreferred; - if(currDrawGlobalYPreferred < mNotWrapLimitYBottom){ + private int limitY(int currDrawGlobalYPreferred) { + if (mWrapSelectorWheel && mWrapSelectorWheelCheck) return currDrawGlobalYPreferred; + if (currDrawGlobalYPreferred < mNotWrapLimitYBottom) { currDrawGlobalYPreferred = mNotWrapLimitYBottom; - }else if(currDrawGlobalYPreferred > mNotWrapLimitYTop){ + } else if (currDrawGlobalYPreferred > mNotWrapLimitYTop) { currDrawGlobalYPreferred = mNotWrapLimitYTop; } return currDrawGlobalYPreferred; } private boolean mFlagMayPress = false; + @Override public boolean onTouchEvent(MotionEvent event) { - if(mItemHeight == 0) return true; + if (mItemHeight == 0) return true; if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); @@ -1025,7 +1037,7 @@ public boolean onTouchEvent(MotionEvent event) { mVelocityTracker.addMovement(event); currY = event.getY(); - switch(event.getAction()){ + switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mFlagMayPress = true; mHandlerInNewThread.removeMessages(HANDLER_WHAT_REFRESH); @@ -1038,20 +1050,20 @@ public boolean onTouchEvent(MotionEvent event) { case MotionEvent.ACTION_MOVE: float spanY = downY - currY; - if(mFlagMayPress && (-mScaledTouchSlop < spanY && spanY < mScaledTouchSlop)){ + if (mFlagMayPress && (-mScaledTouchSlop < spanY && spanY < mScaledTouchSlop)) { - }else{ + } else { mFlagMayPress = false; - mCurrDrawGlobalY = limitY((int)(downYGlobal + spanY)); + mCurrDrawGlobalY = limitY((int) (downYGlobal + spanY)); calculateFirstItemParameterByGlobalY(); invalidate(); } onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); break; case MotionEvent.ACTION_UP: - if(mFlagMayPress){ + if (mFlagMayPress) { click(event); - }else { + } else { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000); int velocityY = (int) (velocityTracker.getYVelocity() * mFriction); @@ -1071,31 +1083,31 @@ public boolean onTouchEvent(MotionEvent event) { mHandlerInNewThread.sendMessageDelayed(getMsg(HANDLER_WHAT_REFRESH), 0); break; } - return true ; + return true; } - private void click(MotionEvent event){ + private void click(MotionEvent event) { float y = event.getY(); - for(int i = 0; i < mShowCount; i++){ - if(mItemHeight * i <= y && y < mItemHeight * (i + 1)){ + for (int i = 0; i < mShowCount; i++) { + if (mItemHeight * i <= y && y < mItemHeight * (i + 1)) { clickItem(i); break; } } } - private void clickItem(int showCountIndex){ - if(0 <= showCountIndex && showCountIndex < mShowCount) { + private void clickItem(int showCountIndex) { + if (0 <= showCountIndex && showCountIndex < mShowCount) { //clicked the showCountIndex of the view - scrollByIndexSmoothly(showCountIndex - mShowCount/2); - }else{ + scrollByIndexSmoothly(showCountIndex - mShowCount / 2); + } else { //wrong } } - private float getTextCenterYOffset(Paint.FontMetrics fontMetrics){ - if(fontMetrics == null) return 0; - return Math.abs(fontMetrics.top + fontMetrics.bottom)/2; + private float getTextCenterYOffset(Paint.FontMetrics fontMetrics) { + if (fontMetrics == null) return 0; + return Math.abs(fontMetrics.top + fontMetrics.bottom) / 2; } private int mViewWidth; @@ -1106,17 +1118,17 @@ private float getTextCenterYOffset(Paint.FontMetrics fontMetrics){ private float mViewCenterX; //defaultPickedIndex relative to the shown part - private void correctPositionByDefaultValue(int defaultPickedIndex, boolean wrap){ + private void correctPositionByDefaultValue(int defaultPickedIndex, boolean wrap) { mCurrDrawFirstItemIndex = defaultPickedIndex - (mShowCount - 1) / 2; mCurrDrawFirstItemIndex = getIndexByRawIndex(mCurrDrawFirstItemIndex, getOneRecycleSize(), wrap); - if(mItemHeight == 0){ + if (mItemHeight == 0) { mCurrentItemIndexEffect = true; - }else { + } else { mCurrDrawGlobalY = mCurrDrawFirstItemIndex * mItemHeight; mInScrollingPickedOldValue = mCurrDrawFirstItemIndex + mShowCount / 2; mInScrollingPickedOldValue = mInScrollingPickedOldValue % getOneRecycleSize(); - if (mInScrollingPickedOldValue < 0){ + if (mInScrollingPickedOldValue < 0) { mInScrollingPickedOldValue = mInScrollingPickedOldValue + getOneRecycleSize(); } mInScrollingPickedNewValue = mInScrollingPickedOldValue; @@ -1133,7 +1145,7 @@ private void correctPositionByDefaultValue(int defaultPickedIndex, boolean wrap) @Override public void computeScroll() { - if(mItemHeight == 0) return; + if (mItemHeight == 0) return; if (mScroller.computeScrollOffset()) { mCurrDrawGlobalY = mScroller.getCurrY(); calculateFirstItemParameterByGlobalY(); @@ -1141,20 +1153,20 @@ public void computeScroll() { } } - private void calculateFirstItemParameterByGlobalY(){ - mCurrDrawFirstItemIndex = (int)Math.floor((float)mCurrDrawGlobalY / mItemHeight); + private void calculateFirstItemParameterByGlobalY() { + mCurrDrawFirstItemIndex = (int) Math.floor((float) mCurrDrawGlobalY / mItemHeight); mCurrDrawFirstItemY = -(mCurrDrawGlobalY - mCurrDrawFirstItemIndex * mItemHeight); - if (mOnValueChangeListenerInScrolling != null){ - if (-mCurrDrawFirstItemY > mItemHeight / 2){ + if (mOnValueChangeListenerInScrolling != null) { + if (-mCurrDrawFirstItemY > mItemHeight / 2) { mInScrollingPickedNewValue = mCurrDrawFirstItemIndex + 1 + mShowCount / 2; - }else{ + } else { mInScrollingPickedNewValue = mCurrDrawFirstItemIndex + mShowCount / 2; } mInScrollingPickedNewValue = mInScrollingPickedNewValue % getOneRecycleSize(); - if (mInScrollingPickedNewValue < 0){ + if (mInScrollingPickedNewValue < 0) { mInScrollingPickedNewValue = mInScrollingPickedNewValue + getOneRecycleSize(); } - if (mInScrollingPickedOldValue != mInScrollingPickedNewValue){ + if (mInScrollingPickedOldValue != mInScrollingPickedNewValue) { respondPickedValueChangedInScrolling(mInScrollingPickedOldValue, mInScrollingPickedNewValue); } mInScrollingPickedOldValue = mInScrollingPickedNewValue; @@ -1162,18 +1174,18 @@ private void calculateFirstItemParameterByGlobalY(){ } private void releaseVelocityTracker() { - if(mVelocityTracker != null) { + if (mVelocityTracker != null) { mVelocityTracker.clear(); mVelocityTracker.recycle(); mVelocityTracker = null; } } - private void updateMaxWHOfDisplayedValues(boolean needRequestLayout){ + private void updateMaxWHOfDisplayedValues(boolean needRequestLayout) { updateMaxWidthOfDisplayedValues(); updateMaxHeightOfDisplayedValues(); - if(needRequestLayout && - (mSpecModeW == MeasureSpec.AT_MOST || mSpecModeH == MeasureSpec.AT_MOST)){ + if (needRequestLayout && + (mSpecModeW == MeasureSpec.AT_MOST || mSpecModeH == MeasureSpec.AT_MOST)) { mHandlerInMainThread.sendEmptyMessage(HANDLER_WHAT_REQUEST_LAYOUT); } } @@ -1228,43 +1240,50 @@ protected void onDraw(Canvas canvas) { drawHint(canvas); } - private void drawContent(Canvas canvas){ + private void drawContent(Canvas canvas) { int index; int textColor; float textSize; float fraction = 0f;// fraction of the item in state between normal and selected, in[0, 1] float textSizeCenterYOffset; - for(int i = 0; i < mShowCount + 1; i++){ + for (int i = 0; i < mShowCount + 1; i++) { float y = mCurrDrawFirstItemY + mItemHeight * i; index = getIndexByRawIndex(mCurrDrawFirstItemIndex + i, getOneRecycleSize(), mWrapSelectorWheel && mWrapSelectorWheelCheck); - if(i == mShowCount / 2){//this will be picked - fraction = (float)(mItemHeight + mCurrDrawFirstItemY) / mItemHeight; + if (i == mShowCount / 2) {//this will be picked + fraction = (float) (mItemHeight + mCurrDrawFirstItemY) / mItemHeight; textColor = getEvaluateColor(fraction, mTextColorNormal, mTextColorSelected); textSize = getEvaluateSize(fraction, mTextSizeNormal, mTextSizeSelected); textSizeCenterYOffset = getEvaluateSize(fraction, mTextSizeNormalCenterYOffset, mTextSizeSelectedCenterYOffset); - }else if(i == mShowCount / 2 + 1){ + } else if (i == mShowCount / 2 + 1) { textColor = getEvaluateColor(1 - fraction, mTextColorNormal, mTextColorSelected); textSize = getEvaluateSize(1 - fraction, mTextSizeNormal, mTextSizeSelected); textSizeCenterYOffset = getEvaluateSize(1 - fraction, mTextSizeNormalCenterYOffset, mTextSizeSelectedCenterYOffset); - }else{ + } else { textColor = mTextColorNormal; textSize = mTextSizeNormal; textSizeCenterYOffset = mTextSizeNormalCenterYOffset; } - mPaintText.setColor(textColor); - mPaintText.setTextSize(textSize); - if(0 <= index && index < getOneRecycleSize()){ + //mPaintText.setColor(textColor); + //mPaintText.setTextSize(textSize); + + if (0 <= index && index < getOneRecycleSize()) { CharSequence str = mDisplayedValues[index + mMinShowIndex]; if (mTextEllipsize != null) { str = TextUtils.ellipsize(str, mPaintText, getWidth() - 2 * mItemPaddingHorizontal, getEllipsizeType()); } + + //自动缩放自适应 text + int autoTextSize = AutoMeasureDelegate.autoMeasureTextSize(textSize, getWidth(), str.toString()); + mPaintText.setColor(textColor); + mPaintText.setTextSize(autoTextSize); + canvas.drawText(str.toString(), mViewCenterX, y + mItemHeight / 2 + textSizeCenterYOffset, mPaintText); - } else if(!TextUtils.isEmpty(mEmptyItemHint)){ + } else if (!TextUtils.isEmpty(mEmptyItemHint)) { canvas.drawText(mEmptyItemHint, mViewCenterX, y + mItemHeight / 2 + textSizeCenterYOffset, mPaintText); } @@ -1284,8 +1303,8 @@ private TextUtils.TruncateAt getEllipsizeType() { } } - private void drawLine(Canvas canvas){ - if(mShowDivider){ + private void drawLine(Canvas canvas) { + if (mShowDivider) { canvas.drawLine(getPaddingLeft() + mDividerMarginL, dividerY0, mViewWidth - getPaddingRight() - mDividerMarginR, dividerY0, mPaintDivider); canvas.drawLine(getPaddingLeft() + mDividerMarginL, @@ -1293,14 +1312,14 @@ private void drawLine(Canvas canvas){ } } - private void drawHint(Canvas canvas){ - if(TextUtils.isEmpty(mHintText)) return; + private void drawHint(Canvas canvas) { + if (TextUtils.isEmpty(mHintText)) return; canvas.drawText(mHintText, - mViewCenterX + (mMaxWidthOfDisplayedValues + mWidthOfHintText)/2 + mMarginStartOfHint, + mViewCenterX + (mMaxWidthOfDisplayedValues + mWidthOfHintText) / 2 + mMarginStartOfHint, (dividerY0 + dividerY1) / 2 + mTextSizeHintCenterYOffset, mPaintHint); } - private void updateMaxWidthOfDisplayedValues(){ + private void updateMaxWidthOfDisplayedValues() { float savedTextSize = mPaintText.getTextSize(); mPaintText.setTextSize(mTextSizeSelected); mMaxWidthOfDisplayedValues = getMaxWidthOfTextArray(mDisplayedValues, mPaintText); @@ -1311,13 +1330,13 @@ private void updateMaxWidthOfDisplayedValues(){ mPaintText.setTextSize(savedTextSize); } - private int getMaxWidthOfTextArray(CharSequence[] array, Paint paint){ - if(array == null){ + private int getMaxWidthOfTextArray(CharSequence[] array, Paint paint) { + if (array == null) { return 0; } int maxWidth = 0; - for(CharSequence item : array){ - if(item != null){ + for (CharSequence item : array) { + if (item != null) { int itemWidth = getTextWidth(item, paint); maxWidth = Math.max(itemWidth, maxWidth); } @@ -1325,60 +1344,60 @@ private int getMaxWidthOfTextArray(CharSequence[] array, Paint paint){ return maxWidth; } - private int getTextWidth(CharSequence text, Paint paint){ - if(!TextUtils.isEmpty(text)){ - return (int)(paint.measureText(text.toString()) + 0.5f); + private int getTextWidth(CharSequence text, Paint paint) { + if (!TextUtils.isEmpty(text)) { + return (int) (paint.measureText(text.toString()) + 0.5f); } return 0; } - private void updateMaxHeightOfDisplayedValues(){ + private void updateMaxHeightOfDisplayedValues() { float savedTextSize = mPaintText.getTextSize(); mPaintText.setTextSize(mTextSizeSelected); - mMaxHeightOfDisplayedValues = (int)(mPaintText.getFontMetrics().bottom - mPaintText.getFontMetrics().top + 0.5); + mMaxHeightOfDisplayedValues = (int) (mPaintText.getFontMetrics().bottom - mPaintText.getFontMetrics().top + 0.5); mPaintText.setTextSize(savedTextSize); } - private void updateContentAndIndex(String[] newDisplayedValues){ + private void updateContentAndIndex(String[] newDisplayedValues) { mMinShowIndex = 0; mMaxShowIndex = newDisplayedValues.length - 1; mDisplayedValues = newDisplayedValues; updateWrapStateByContent(); } - private void updateContent(String[] newDisplayedValues){ + private void updateContent(String[] newDisplayedValues) { mDisplayedValues = newDisplayedValues; updateWrapStateByContent(); } //used in setDisplayedValues - private void updateValue(){ + private void updateValue() { inflateDisplayedValuesIfNull(); updateWrapStateByContent(); mMinShowIndex = 0; mMaxShowIndex = mDisplayedValues.length - 1; } - private void updateValueForInit(){ + private void updateValueForInit() { inflateDisplayedValuesIfNull(); updateWrapStateByContent(); - if(mMinShowIndex == -1){ + if (mMinShowIndex == -1) { mMinShowIndex = 0; } - if(mMaxShowIndex == -1){ + if (mMaxShowIndex == -1) { mMaxShowIndex = mDisplayedValues.length - 1; } setMinAndMaxShowIndex(mMinShowIndex, mMaxShowIndex, false); } - private void inflateDisplayedValuesIfNull(){ - if(mDisplayedValues == null) { + private void inflateDisplayedValuesIfNull() { + if (mDisplayedValues == null) { mDisplayedValues = new String[1]; mDisplayedValues[0] = "0"; } } - private void updateWrapStateByContent(){ + private void updateWrapStateByContent() { mWrapSelectorWheelCheck = mDisplayedValues.length <= mShowCount ? false : true; } @@ -1391,24 +1410,24 @@ private int refineValueByLimit(int value, int minValue, int maxValue, boolean wr } return value; } else { - if(value > maxValue){ + if (value > maxValue) { value = maxValue; - }else if(value < minValue){ + } else if (value < minValue) { value = minValue; } return value; } } - private void stopRefreshing(){ - if (mHandlerInNewThread != null){ + private void stopRefreshing() { + if (mHandlerInNewThread != null) { mHandlerInNewThread.removeMessages(HANDLER_WHAT_REFRESH); } } - public void stopScrolling(){ - if(mScroller != null){ - if(!mScroller.isFinished()){ + public void stopScrolling() { + if (mScroller != null) { + if (!mScroller.isFinished()) { mScroller.startScroll(0, mScroller.getCurrY(), 0, 0, 1); mScroller.abortAnimation(); postInvalidate(); @@ -1416,18 +1435,18 @@ public void stopScrolling(){ } } - public void stopScrollingAndCorrectPosition(){ + public void stopScrollingAndCorrectPosition() { stopScrolling(); - if (mHandlerInNewThread != null){ + if (mHandlerInNewThread != null) { mHandlerInNewThread.sendMessageDelayed(getMsg(HANDLER_WHAT_REFRESH), 0); } } - private Message getMsg(int what){ + private Message getMsg(int what) { return getMsg(what, 0, 0, null); } - private Message getMsg(int what, int arg1, int arg2, Object obj){ + private Message getMsg(int what, int arg1, int arg2, Object obj) { Message msg = Message.obtain(); msg.what = what; msg.arg1 = arg1; @@ -1437,14 +1456,14 @@ private Message getMsg(int what, int arg1, int arg2, Object obj){ } //===tool functions===// - private boolean isStringEqual(String a, String b){ - if(a == null){ - if(b == null){ + private boolean isStringEqual(String a, String b) { + if (a == null) { + if (b == null) { return true; - }else{ + } else { return false; } - }else{ + } else { return a.equals(b); } } @@ -1459,7 +1478,7 @@ private int dp2px(Context context, float dpValue) { return (int) (dpValue * densityScale + 0.5f); } - private int getEvaluateColor(float fraction, int startColor, int endColor){ + private int getEvaluateColor(float fraction, int startColor, int endColor) { int a, r, g, b; @@ -1473,22 +1492,22 @@ private int getEvaluateColor(float fraction, int startColor, int endColor){ int eG = (endColor & 0x0000ff00) >>> 8; int eB = (endColor & 0x000000ff) >>> 0; - a = (int)(sA + (eA - sA) * fraction); - r = (int)(sR + (eR - sR) * fraction); - g = (int)(sG + (eG - sG) * fraction); - b = (int)(sB + (eB - sB) * fraction); + a = (int) (sA + (eA - sA) * fraction); + r = (int) (sR + (eR - sR) * fraction); + g = (int) (sG + (eG - sG) * fraction); + b = (int) (sB + (eB - sB) * fraction); return a << 24 | r << 16 | g << 8 | b; } - private float getEvaluateSize(float fraction, float startSize, float endSize){ + private float getEvaluateSize(float fraction, float startSize, float endSize) { return startSize + (endSize - startSize) * fraction; } - private String[] convertCharSequenceArrayToStringArray(CharSequence[] charSequences){ - if(charSequences == null) return null; + private String[] convertCharSequenceArrayToStringArray(CharSequence[] charSequences) { + if (charSequences == null) return null; String[] ret = new String[charSequences.length]; - for(int i = 0; i < charSequences.length; i++){ + for (int i = 0; i < charSequences.length; i++) { ret[i] = charSequences[i].toString(); } return ret; diff --git a/library/src/main/java/cn/carbswang/android/numberpickerview/library/delagate/AutoMeasureDelegate.java b/library/src/main/java/cn/carbswang/android/numberpickerview/library/delagate/AutoMeasureDelegate.java new file mode 100644 index 0000000..0d5ea74 --- /dev/null +++ b/library/src/main/java/cn/carbswang/android/numberpickerview/library/delagate/AutoMeasureDelegate.java @@ -0,0 +1,28 @@ +package cn.carbswang.android.numberpickerview.library.delagate; + +import android.graphics.Paint; + +/** + * Created by uni7corn + *

+ * on 2018/11/16 + * desc: 修正显示的内容,自动测量文本大小,当文本大小超过了控件大小时,自动缩放文本内容 + */ +public class AutoMeasureDelegate { + + public static int autoMeasureTextSize(float textSize, float totalWidth, String content) { + Paint measurePint = new Paint(); + measurePint.setTextSize(textSize); + float measureTextWidth = measureText(measurePint, content); + //Log.e(TAG, "PaintTextSize=${textPaint.textSize} textSize=$textSize measureTextWidth=$measureTextWidth totalWidth=$totalWidth contentByCurrValue=$contentByCurrValue") + if (measureTextWidth >= totalWidth) {//超过了控件大小,(ps:当 measureTextWidth==totalWidth(不让文本贴合在控件边框)))需要进行缩放即 scaleTextSize=textSize-1 + return autoMeasureTextSize(textSize - 1, totalWidth, content); + } else {//小于控件大小,直接返回 + return (int) textSize; + } + } + + private static float measureText(Paint textPaint, String content) { + return (textPaint.measureText(content) + 0.5f); + } +} From f80b4bf464c7e993e5aa6a4d019f498ed129487c Mon Sep 17 00:00:00 2001 From: uni7corn Date: Fri, 16 Nov 2018 16:19:43 +0800 Subject: [PATCH 4/5] =?UTF-8?q?[feature][=E9=A2=84=E8=A7=88=E5=9B=BE]?= =?UTF-8?q?=EF=BC=9A=E5=8A=A0=E5=85=A5gif=E9=A2=84=E8=A7=88=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- picture/scaleAutoTextNumberPickerView.gif | Bin 0 -> 32588 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 picture/scaleAutoTextNumberPickerView.gif diff --git a/picture/scaleAutoTextNumberPickerView.gif b/picture/scaleAutoTextNumberPickerView.gif new file mode 100644 index 0000000000000000000000000000000000000000..df952b7a6bb3a153deb8223cb42e66cfe55358b0 GIT binary patch literal 32588 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 TlCRaXYP}~mHUKz~;`;vrm5c~0 literal 0 HcmV?d00001 From d5065dfba9e413bea247200adb15c324ce4ce7a8 Mon Sep 17 00:00:00 2001 From: uni7corn <287890808@qq.com> Date: Fri, 16 Nov 2018 16:32:25 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加gif 预览图 --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9bec799..6afc8c7 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,12 @@ 在Android项目的开发中会用到`NumberPicker`组件,但是默认风格的`NumberPicker`具有一些不灵活的属性,定制起来也比较麻烦,并且缺少一些过渡动效,因此在应用开发时,一般采用自定义的控件来完成选择功能。 ### 控件截图 -==== + +- [x] 感谢作者 [Carbs0126](https://github.com/Carbs0126/NumberPickerView) +#### 自适应内容文本 (当文本内容大小超过控件宽度时,自适应) + +![自适应文本大小](https://github.com/uni7corn/NumberPickerView/blob/master/picture/scaleAutoTextNumberPickerView.gif "自适应文本大小")
+ ![Example Image][4]
效果图1