diff --git a/README.md b/README.md index 5bf175b..47b3bdb 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ It's based on [android.widget.NumberPicker](https://android.googlesource.com/pla - Customizable fonts(color, size, typeface) - Customizable dividers(color, distance, thickness) - Horizontal and Vertical mode are both supported +- Ascending and Descending order are both supported - Also supports the negative values ## Usage @@ -70,9 +71,9 @@ add `xmlns:app="http://schemas.android.com/apk/res-auto"` app:np_max="59" app:np_min="0" app:np_selectedTextColor="@color/colorPrimary" + app:np_selectedTextSize="@dimen/selected_text_size" app:np_textColor="@color/colorPrimary" app:np_textSize="@dimen/text_size" - app:np_selectedTextSize="@dimen/selected_text_size" app:np_typeface="@string/roboto_light" app:np_value="3" /> ``` @@ -89,11 +90,12 @@ add `xmlns:app="http://schemas.android.com/apk/res-auto"` |np_formatter|The formatter of the numbers.| |np_max|The max value of this widget.| |np_min|The min value of this widget.| +|np_order|The order of this widget. Default is ascending.| |np_orientation|The orientation of this widget. Default is vertical.| |np_selectedTextColor|The text color of the selected number.| +|np_selectedTextSize|The text size of the selected number.| |np_textColor|The text color of the numbers.| |np_textSize|The text size of the numbers.| -|np_selectedTextSize|The text size of the selected number.| |np_typeface|The typeface of the numbers.| |np_value|The current value of this widget.| |np_wheelItemCount|The number of items show in the selector wheel.| @@ -111,7 +113,7 @@ buildscript { } dependencies { - compile 'com.shawnlin:number-picker:2.4.3' + compile 'com.shawnlin:number-picker:2.4.4' } ``` diff --git a/gradle.properties b/gradle.properties index 65c7309..d5f6af6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -VERSION_CODE=11 -VERSION_NAME=2.4.3 +VERSION_CODE=12 +VERSION_NAME=2.4.4 GROUP=com.shawnlin ARTIFACT_ID=number-picker diff --git a/library/src/main/java/com/shawnlin/numberpicker/NumberPicker.java b/library/src/main/java/com/shawnlin/numberpicker/NumberPicker.java index 74663d0..bb84486 100644 --- a/library/src/main/java/com/shawnlin/numberpicker/NumberPicker.java +++ b/library/src/main/java/com/shawnlin/numberpicker/NumberPicker.java @@ -51,9 +51,15 @@ public class NumberPicker extends LinearLayout { public @interface Orientation{} public static final int VERTICAL = LinearLayout.VERTICAL; - public static final int HORIZONTAL = LinearLayout.HORIZONTAL; + @Retention(SOURCE) + @IntDef({ASCENDING, DESCENDING}) + public @interface Order{} + + public static final int ASCENDING = 0; + public static final int DESCENDING = 1; + /** * The default update interval during long press. */ @@ -94,6 +100,11 @@ public class NumberPicker extends LinearLayout { */ private static final int SIZE_UNSPECIFIED = -1; + /** + * The default color of divider. + */ + private static final int DEFAULT_DIVIDER_COLOR = 0xFF000000; + /** * The default max value of this widget. */ @@ -403,7 +414,7 @@ public static final Formatter getTwoDigitFormatter() { /** * The color of the selection divider. */ - private int mSelectionDividerColor; + private int mSelectionDividerColor = DEFAULT_DIVIDER_COLOR; /** * The distance between the two selection dividers. @@ -460,6 +471,11 @@ public static final Formatter getTwoDigitFormatter() { */ private int mOrientation; + /** + * The order of this widget. + */ + private int mOrder; + /** * The context of this widget. */ @@ -574,6 +590,7 @@ public NumberPicker(Context context, AttributeSet attrs, int defStyle) { mSelectionDividerThickness = attributesArray.getDimensionPixelSize( R.styleable.NumberPicker_np_dividerThickness, defSelectionDividerThickness); + mOrder = attributesArray.getInt(R.styleable.NumberPicker_np_order, ASCENDING); mOrientation = attributesArray.getInt(R.styleable.NumberPicker_np_orientation, VERTICAL); mWidth = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_np_width, SIZE_UNSPECIFIED); @@ -588,9 +605,9 @@ public NumberPicker(Context context, AttributeSet attrs, int defStyle) { mMinValue = attributesArray.getInt(R.styleable.NumberPicker_np_min, mMinValue); mSelectedTextColor = attributesArray.getColor(R.styleable.NumberPicker_np_selectedTextColor, mSelectedTextColor); + mSelectedTextSize = attributesArray.getDimension(R.styleable.NumberPicker_np_selectedTextSize, spToPx(mSelectedTextSize)); mTextColor = attributesArray.getColor(R.styleable.NumberPicker_np_textColor, mTextColor); mTextSize = attributesArray.getDimension(R.styleable.NumberPicker_np_textSize, spToPx(mTextSize)); - mSelectedTextSize = attributesArray.getDimension(R.styleable.NumberPicker_np_selectedTextSize, spToPx(mSelectedTextSize)); mTypeface = Typeface.create(attributesArray.getString(R.styleable.NumberPicker_np_typeface), Typeface.NORMAL); mFormatter = stringToFormatter(attributesArray.getString(R.styleable.NumberPicker_np_formatter)); mWheelItemCount = attributesArray.getInt(R.styleable.NumberPicker_np_wheelItemCount, mWheelItemCount); @@ -1003,32 +1020,58 @@ public void setEnabled(boolean enabled) { @Override public void scrollBy(int x, int y) { - int[] selectorIndices = mSelectorIndices; + int[] selectorIndices = getSelectorIndices(); int gap; if (isHorizontalMode()) { - if (!mWrapSelectorWheel && x > 0 - && selectorIndices[mWheelMiddleItemIndex] <= mMinValue) { - mCurrentScrollOffset = mInitialScrollOffset; - return; - } - if (!mWrapSelectorWheel && x < 0 - && selectorIndices[mWheelMiddleItemIndex] >= mMaxValue) { - mCurrentScrollOffset = mInitialScrollOffset; - return; + if (isAscendingOrder()) { + if (!mWrapSelectorWheel && x > 0 + && selectorIndices[mWheelMiddleItemIndex] <= mMinValue) { + mCurrentScrollOffset = mInitialScrollOffset; + return; + } + if (!mWrapSelectorWheel && x < 0 + && selectorIndices[mWheelMiddleItemIndex] >= mMaxValue) { + mCurrentScrollOffset = mInitialScrollOffset; + return; + } + } else { + if (!mWrapSelectorWheel && x > 0 + && selectorIndices[mWheelMiddleItemIndex] >= mMaxValue) { + mCurrentScrollOffset = mInitialScrollOffset; + return; + } + if (!mWrapSelectorWheel && x < 0 + && selectorIndices[mWheelMiddleItemIndex] <= mMinValue) { + mCurrentScrollOffset = mInitialScrollOffset; + return; + } } mCurrentScrollOffset += x; gap = mSelectorTextGapWidth; } else { - if (!mWrapSelectorWheel && y > 0 - && selectorIndices[mWheelMiddleItemIndex] <= mMinValue) { - mCurrentScrollOffset = mInitialScrollOffset; - return; - } - if (!mWrapSelectorWheel && y < 0 - && selectorIndices[mWheelMiddleItemIndex] >= mMaxValue) { - mCurrentScrollOffset = mInitialScrollOffset; - return; + if (isAscendingOrder()) { + if (!mWrapSelectorWheel && y > 0 + && selectorIndices[mWheelMiddleItemIndex] <= mMinValue) { + mCurrentScrollOffset = mInitialScrollOffset; + return; + } + if (!mWrapSelectorWheel && y < 0 + && selectorIndices[mWheelMiddleItemIndex] >= mMaxValue) { + mCurrentScrollOffset = mInitialScrollOffset; + return; + } + } else { + if (!mWrapSelectorWheel && y > 0 + && selectorIndices[mWheelMiddleItemIndex] >= mMaxValue) { + mCurrentScrollOffset = mInitialScrollOffset; + return; + } + if (!mWrapSelectorWheel && y < 0 + && selectorIndices[mWheelMiddleItemIndex] <= mMinValue) { + mCurrentScrollOffset = mInitialScrollOffset; + return; + } } mCurrentScrollOffset += y; @@ -1037,7 +1080,11 @@ public void scrollBy(int x, int y) { while (mCurrentScrollOffset - mInitialScrollOffset > gap) { mCurrentScrollOffset -= mSelectorElementSize; - decrementSelectorIndices(selectorIndices); + if (isAscendingOrder()) { + decrementSelectorIndices(selectorIndices); + } else { + incrementSelectorIndices(selectorIndices); + } setValueInternal(selectorIndices[mWheelMiddleItemIndex], true); if (!mWrapSelectorWheel && selectorIndices[mWheelMiddleItemIndex] < mMinValue) { mCurrentScrollOffset = mInitialScrollOffset; @@ -1045,7 +1092,11 @@ public void scrollBy(int x, int y) { } while (mCurrentScrollOffset - mInitialScrollOffset < -gap) { mCurrentScrollOffset += mSelectorElementSize; - incrementSelectorIndices(selectorIndices); + if (isAscendingOrder()) { + incrementSelectorIndices(selectorIndices); + } else { + decrementSelectorIndices(selectorIndices); + } setValueInternal(selectorIndices[mWheelMiddleItemIndex], true); if (!mWrapSelectorWheel && selectorIndices[mWheelMiddleItemIndex] > mMaxValue) { mCurrentScrollOffset = mInitialScrollOffset; @@ -1369,7 +1420,7 @@ protected void onDraw(Canvas canvas) { } // draw the selector wheel - int[] selectorIndices = mSelectorIndices; + int[] selectorIndices = getSelectorIndices(); for (int i = 0; i < selectorIndices.length; i++) { if (i == mWheelMiddleItemIndex) { mSelectorWheelPaint.setTextSize(mSelectedTextSize); @@ -1379,7 +1430,7 @@ protected void onDraw(Canvas canvas) { mSelectorWheelPaint.setColor(mTextColor); } - int selectorIndex = selectorIndices[i]; + int selectorIndex = selectorIndices[isAscendingOrder() ? i : selectorIndices.length - i - 1]; 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 @@ -1528,7 +1579,7 @@ public static int resolveSizeAndState(int size, int measureSpec, int childMeasur */ private void initializeSelectorWheelIndices() { mSelectorIndexToStringCache.clear(); - int[] selectorIndices = mSelectorIndices; + int[] selectorIndices = getSelectorIndices(); int current = getValue(); for (int i = 0; i < mSelectorIndices.length; i++) { int selectorIndex = current + (i - mWheelMiddleItemIndex); @@ -1599,7 +1650,7 @@ private void changeValueByOne(boolean increment) { private void initializeSelectorWheel() { initializeSelectorWheelIndices(); - int[] selectorIndices = mSelectorIndices; + int[] selectorIndices = getSelectorIndices(); int totalTextSize = selectorIndices.length * (int) mTextSize; float textGapCount = selectorIndices.length; int editTextTextPosition; @@ -1693,6 +1744,10 @@ private int getWrappedSelectorIndex(int selectorIndex) { return selectorIndex; } + private int[] getSelectorIndices() { + return mSelectorIndices; + } + /** * Increments the selectorIndices whose string representations * will be displayed in the selector. @@ -2038,6 +2093,15 @@ public void setDividerThickness(int thickness) { mSelectionDividerThickness = (int) dpToPx(thickness); } + /** + * Should sort numbers in ascending or descending order. + * @param order Pass {@link #ASCENDING} or {@link #ASCENDING}. + * Default value is {@link #DESCENDING}. + */ + public void setOrder(@Order int order) { + mOrder = order; + } + public void setOrientation(@Orientation int orientation) { mOrientation = orientation; setWidthAndHeight(); @@ -2070,6 +2134,15 @@ public void setSelectedTextColorResource(@ColorRes int colorId) { setSelectedTextColor(ContextCompat.getColor(mContext, colorId)); } + public void setSelectedTextSize(float textSize) { + mSelectedTextSize = textSize; + mSelectedText.setTextSize(pxToSp(mSelectedTextSize)); + } + + public void setSelectedTextSize(@DimenRes int dimenId) { + setSelectedTextSize(getResources().getDimension(dimenId)); + } + public void setTextColor(@ColorInt int color) { mTextColor = color; mSelectorWheelPaint.setColor(mTextColor); @@ -2087,14 +2160,7 @@ public void setTextSize(float textSize) { public void setTextSize(@DimenRes int dimenId) { setTextSize(getResources().getDimension(dimenId)); } - public void setSelectedTextSize(float textSize) { - mSelectedTextSize = textSize; - mSelectedText.setTextSize(pxToSp(mSelectedTextSize)); - } - public void setSelectedTextSize(@DimenRes int dimenId) { - setSelectedTextSize(getResources().getDimension(dimenId)); - } public void setTypeface(Typeface typeface) { mTypeface = typeface; if (mTypeface != null) { @@ -2155,7 +2221,11 @@ private float pxToSp(float px) { } public boolean isHorizontalMode() { - return mOrientation == HORIZONTAL; + return getOrientation() == HORIZONTAL; + } + + public boolean isAscendingOrder() { + return getOrder() == ASCENDING; } public int getDividerColor() { @@ -2170,6 +2240,10 @@ public float getDividerThickness() { return pxToDp(mSelectionDividerThickness); } + public int getOrder() { + return mOrder; + } + public int getOrientation() { return mOrientation; } @@ -2186,6 +2260,10 @@ public int getSelectedTextColor() { return mSelectedTextColor; } + public float getSelectedTextSize() { + return mSelectedTextSize; + } + public int getTextColor() { return mTextColor; } @@ -2198,7 +2276,4 @@ public Typeface getTypeface() { return mTypeface; } - public float getmSelectedTextSize() { - return mSelectedTextSize; - } } diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index e7ab119..235d1ce 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -12,14 +12,18 @@ + + + + + - diff --git a/sample/src/main/java/com/shawnlin/numberpicker/sample/MainActivity.java b/sample/src/main/java/com/shawnlin/numberpicker/sample/MainActivity.java index 1beac55..e1f3042 100644 --- a/sample/src/main/java/com/shawnlin/numberpicker/sample/MainActivity.java +++ b/sample/src/main/java/com/shawnlin/numberpicker/sample/MainActivity.java @@ -31,6 +31,10 @@ protected void onCreate(Bundle savedInstanceState) { numberPicker.setSelectedTextColor(ContextCompat.getColor(this, R.color.colorPrimary)); numberPicker.setSelectedTextColorResource(R.color.colorPrimary); + // set selected text size + numberPicker.setSelectedTextSize(getResources().getDimension(R.dimen.selected_text_size)); + numberPicker.setSelectedTextSize(R.dimen.selected_text_size); + // set text color numberPicker.setTextColor(ContextCompat.getColor(this, R.color.dark_grey)); numberPicker.setTextColorResource(R.color.dark_grey); @@ -39,10 +43,6 @@ protected void onCreate(Bundle savedInstanceState) { numberPicker.setTextSize(getResources().getDimension(R.dimen.text_size)); numberPicker.setTextSize(R.dimen.text_size); - // set selected text size - numberPicker.setSelectedTextSize(getResources().getDimension(R.dimen.selected_text_size)); - numberPicker.setSelectedTextSize(R.dimen.selected_text_size); - // set typeface numberPicker.setTypeface(Typeface.create(getString(R.string.roboto_light), Typeface.NORMAL)); numberPicker.setTypeface(getString(R.string.roboto_light), Typeface.NORMAL); diff --git a/sample/src/main/res/layout/content_main.xml b/sample/src/main/res/layout/content_main.xml index 3cdf0b6..9870ae9 100644 --- a/sample/src/main/res/layout/content_main.xml +++ b/sample/src/main/res/layout/content_main.xml @@ -31,11 +31,13 @@ app:np_dividerColor="@color/colorAccent" app:np_max="10" app:np_min="0" + app:np_order="descending" app:np_orientation="horizontal" app:np_selectedTextColor="@color/colorAccent" app:np_textColor="@color/colorAccent" app:np_textSize="@dimen/text_size" app:np_selectedTextSize="@dimen/selected_text_size" - app:np_typeface="@string/roboto_light" /> + app:np_typeface="@string/roboto_light" + app:np_wrapSelectorWheel="true" />