From 947c2aa41407c8d2bf0e60ded4c40e197dd86827 Mon Sep 17 00:00:00 2001 From: Alireza Afkar Date: Mon, 29 Feb 2016 13:16:28 +0330 Subject: [PATCH 1/3] RTL support for floatingText, Error and text --- .../materialspinner/MaterialSpinner.java | 118 ++++++++++++++---- library/src/main/res/values/attrs.xml | 5 +- 2 files changed, 94 insertions(+), 29 deletions(-) diff --git a/library/src/main/java/fr/ganfra/materialspinner/MaterialSpinner.java b/library/src/main/java/fr/ganfra/materialspinner/MaterialSpinner.java index 94e87e5..870bf59 100644 --- a/library/src/main/java/fr/ganfra/materialspinner/MaterialSpinner.java +++ b/library/src/main/java/fr/ganfra/materialspinner/MaterialSpinner.java @@ -15,6 +15,7 @@ import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.TypedValue; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -99,7 +100,9 @@ public class MaterialSpinner extends AppCompatSpinner implements ValueAnimator.A private float arrowSize; private boolean enableErrorLabel; private boolean enableFloatingLabel; - private boolean isRtl; + private boolean rtlFloatingLabel; + private boolean rtlError; + private boolean rtlText; private HintAdapter hintAdapter; @@ -173,7 +176,9 @@ private void initAttributes(Context context, AttributeSet attrs) { arrowSize = array.getDimension(R.styleable.MaterialSpinner_ms_arrowSize, dpToPx(DEFAULT_ARROW_WIDTH_DP)); enableErrorLabel = array.getBoolean(R.styleable.MaterialSpinner_ms_enableErrorLabel, true); enableFloatingLabel = array.getBoolean(R.styleable.MaterialSpinner_ms_enableFloatingLabel, true); - isRtl = array.getBoolean(R.styleable.MaterialSpinner_ms_isRtl, false); + rtlFloatingLabel = array.getBoolean(R.styleable.MaterialSpinner_ms_rtlFloatingLabel, false); + rtlError = array.getBoolean(R.styleable.MaterialSpinner_ms_rtlError, false); + rtlText = array.getBoolean(R.styleable.MaterialSpinner_ms_rtlText, false); String typefacePath = array.getString(R.styleable.MaterialSpinner_ms_typeface); if (typefacePath != null) { @@ -298,17 +303,16 @@ private void hideFloatingLabel() { } private void startErrorScrollingAnimator() { - int textWidth = Math.round(textPaint.measureText(error.toString())); if (errorLabelAnimator == null) { - errorLabelAnimator = ObjectAnimator.ofInt(this, "errorLabelPosX", 0, textWidth + getWidth() / 2); + errorLabelAnimator = ObjectAnimator.ofInt(this, "errorLabelPosX", getErrorAnimationValues(textWidth)); errorLabelAnimator.setStartDelay(1000); errorLabelAnimator.setInterpolator(new LinearInterpolator()); errorLabelAnimator.setDuration(150 * error.length()); errorLabelAnimator.addUpdateListener(this); errorLabelAnimator.setRepeatCount(ValueAnimator.INFINITE); } else { - errorLabelAnimator.setIntValues(0, textWidth + getWidth() / 2); + errorLabelAnimator.setIntValues(getErrorAnimationValues(textWidth)); } errorLabelAnimator.start(); } @@ -408,11 +412,11 @@ protected void onDraw(Canvas canvas) { } else { //scrolling - canvas.drawText(error.toString(), startX + rightLeftSpinnerPadding - errorLabelPosX, startYErrorLabel, textPaint); + canvas.drawText(error.toString(), getErrorStartX(error.toString()), startYErrorLabel, textPaint); if (errorLabelPosX > 0) { canvas.save(); canvas.translate(textPaint.measureText(error.toString()) + getWidth() / 2, 0); - canvas.drawText(error.toString(), startX + rightLeftSpinnerPadding - errorLabelPosX, startYErrorLabel, textPaint); + canvas.drawText(error.toString(), getErrorStartX(error.toString()), startYErrorLabel, textPaint); canvas.restore(); } } @@ -440,14 +444,10 @@ protected void onDraw(Canvas canvas) { textPaint.setAlpha((int) ((0.8 * floatingLabelPercent + 0.2) * baseAlpha * floatingLabelPercent)); } String textToDraw = floatingLabelText != null ? floatingLabelText.toString() : hint.toString(); - if (isRtl) { - canvas.drawText(textToDraw, getWidth() - rightLeftSpinnerPadding - textPaint.measureText(textToDraw), startYFloatingLabel, textPaint); - } else { - canvas.drawText(textToDraw, startX + rightLeftSpinnerPadding, startYFloatingLabel, textPaint); - } + canvas.drawText(textToDraw, getFloatingLabelStartX(textToDraw), startYFloatingLabel, textPaint); } - drawSelector(canvas, getWidth() - rightLeftSpinnerPadding, getPaddingTop() + dpToPx(8)); + drawSelector(canvas, getArrowStartX(), getPaddingTop() + dpToPx(8)); } @@ -464,8 +464,8 @@ private void drawSelector(Canvas canvas, int posX, int posY) { Point point3 = selectorPoints[2]; point1.set(posX, posY); - point2.set((int) (posX - (arrowSize)), posY); - point3.set((int) (posX - (arrowSize / 2)), (int) (posY + (arrowSize / 2))); + point2.set(getArrowPositionX(posX, arrowSize), posY); + point3.set(getArrowPositionX(posX, (arrowSize / 2)), (int) (posY + (arrowSize / 2))); selectorPath.reset(); selectorPath.moveTo(point1.x, point1.y); @@ -475,6 +475,46 @@ private void drawSelector(Canvas canvas, int posX, int posY) { canvas.drawPath(selectorPath, paint); } + private int getFloatingLabelStartX(String text) { + if (isRtlFloatingLabel()) { + return (int) (getWidth() - rightLeftSpinnerPadding - textPaint.measureText(text)); + } else { + return rightLeftSpinnerPadding; + } + } + + private int getErrorStartX(String text) { + if (isRtlError()) { + return (int) (getWidth() - textPaint.measureText(text)) - errorLabelPosX; + } else { + return rightLeftSpinnerPadding - errorLabelPosX; + } + } + + private int getArrowStartX() { + if (isRtlText()) { + return rightLeftSpinnerPadding; + } else { + return getWidth() - rightLeftSpinnerPadding; + } + } + + private int getArrowPositionX(int posX, float arrowSize) { + if (isRtlText()) { + return (int) (posX + (arrowSize)); + } else { + return (int) (posX - (arrowSize)); + } + } + + private int[] getErrorAnimationValues(int textWidth) { + if (isRtlError()) { + return new int[]{textWidth + getWidth() / 2, 0}; + } else { + return new int[]{0, textWidth + getWidth() / 2}; + } + } + /* * ********************************************************************************** * LISTENER METHODS @@ -646,14 +686,29 @@ public CharSequence getError() { return this.error; } - public void setRtl() { - isRtl = true; - invalidate(); - } + public boolean isRtlFloatingLabel() { + return rtlFloatingLabel; + } - public boolean isRtl() { - return isRtl; - } + public void setRtlFloatingLabel(boolean rtlFloatingLabel) { + this.rtlFloatingLabel = rtlFloatingLabel; + } + + public boolean isRtlError() { + return rtlError; + } + + public void setRtlError(boolean rtlError) { + this.rtlError = rtlError; + } + + public boolean isRtlText() { + return rtlText; + } + + public void setRtlText(boolean rtlText) { + this.rtlText = rtlText; + } /** * @deprecated {use @link #setPaddingSafe(int, int, int, int)} to keep internal computation OK @@ -795,24 +850,33 @@ public View getDropDownView(int position, View convertView, ViewGroup parent) { private View buildView(int position, View convertView, ViewGroup parent, boolean isDropDownView) { if (getItemViewType(position) == HINT_TYPE) { - return getHintView(convertView, parent, isDropDownView); + return getHintView(parent, isDropDownView); } //workaround to have multiple types in spinner if (convertView != null) { convertView = (convertView.getTag() != null && convertView.getTag() instanceof Integer && (Integer) convertView.getTag() != HINT_TYPE) ? convertView : null; } position = hint != null ? position - 1 : position; - return isDropDownView ? mSpinnerAdapter.getDropDownView(position, convertView, parent) : mSpinnerAdapter.getView(position, convertView, parent); + View view = isDropDownView ? mSpinnerAdapter.getDropDownView(position, convertView, parent) : mSpinnerAdapter.getView(position, convertView, parent); + + if (isRtlText() && view instanceof TextView) { + ((TextView) view).setGravity(Gravity.RIGHT); + } + + return view; } - private View getHintView(final View convertView, final ViewGroup parent, final boolean isDropDownView) { + private View getHintView(final ViewGroup parent, final boolean isDropDownView) { final LayoutInflater inflater = LayoutInflater.from(mContext); - final int resid = isDropDownView ? android.R.layout.simple_spinner_dropdown_item : android.R.layout.simple_spinner_item; - final TextView textView = (TextView) inflater.inflate(resid, parent, false); + final int resId = isDropDownView ? android.R.layout.simple_spinner_dropdown_item : android.R.layout.simple_spinner_item; + final TextView textView = (TextView) inflater.inflate(resId, parent, false); textView.setText(hint); textView.setTextColor(MaterialSpinner.this.isEnabled() ? hintColor : disabledColor); textView.setTag(HINT_TYPE); + if (isRtlText()) { + textView.setGravity(Gravity.RIGHT); + } return textView; } diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index ca1a386..be6bff3 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -19,7 +19,8 @@ - - + + + \ No newline at end of file From 846d77ef470012f9e30929c9d4280b7d4ef79c5c Mon Sep 17 00:00:00 2001 From: Alireza Afkar Date: Mon, 29 Feb 2016 13:17:48 +0330 Subject: [PATCH 2/3] Updated support library to 23.2.0 --- library/build.gradle | 4 ++-- sample/build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/build.gradle b/library/build.gradle index d9afb24..2d8d99d 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -18,8 +18,8 @@ android { dependencies { compile 'com.nineoldandroids:library:2.4.0' - compile 'com.android.support:appcompat-v7:23.1.1' - compile 'com.android.support:recyclerview-v7:23.1.1' + compile 'com.android.support:appcompat-v7:23.2.0' + compile 'com.android.support:recyclerview-v7:23.2.0' } apply from: '../maven_push.gradle' diff --git a/sample/build.gradle b/sample/build.gradle index 256ffa2..2e3d751 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -21,7 +21,7 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:23.1.1' + compile 'com.android.support:appcompat-v7:23.2.0' compile project(':library') } From a870cc1d92dbfd2e5ec7f4818df4a0c95cd33f15 Mon Sep 17 00:00:00 2001 From: Alireza Afkar Date: Mon, 29 Feb 2016 13:24:49 +0330 Subject: [PATCH 3/3] Added disabledColor to attributes & fixed color attributes --- .../java/fr/ganfra/materialspinner/MaterialSpinner.java | 6 ++++-- library/src/main/res/values/attrs.xml | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/library/src/main/java/fr/ganfra/materialspinner/MaterialSpinner.java b/library/src/main/java/fr/ganfra/materialspinner/MaterialSpinner.java index 870bf59..251e60b 100644 --- a/library/src/main/java/fr/ganfra/materialspinner/MaterialSpinner.java +++ b/library/src/main/java/fr/ganfra/materialspinner/MaterialSpinner.java @@ -8,6 +8,7 @@ import android.graphics.Point; import android.graphics.Typeface; import android.os.Build; +import android.support.v4.content.ContextCompat; import android.support.v7.widget.AppCompatSpinner; import android.text.Layout; import android.text.StaticLayout; @@ -154,14 +155,15 @@ private void initAttributes(Context context, AttributeSet attrs) { TypedArray defaultArray = context.obtainStyledAttributes(new int[]{R.attr.colorControlNormal, R.attr.colorAccent}); int defaultBaseColor = defaultArray.getColor(0, 0); int defaultHighlightColor = defaultArray.getColor(1, 0); - int defaultErrorColor = context.getResources().getColor(R.color.error_color); + int defaultErrorColor = ContextCompat.getColor(context, R.color.error_color); + int defaultDisabledColor = ContextCompat.getColor(context, R.color.disabled_color); defaultArray.recycle(); TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MaterialSpinner); baseColor = array.getColor(R.styleable.MaterialSpinner_ms_baseColor, defaultBaseColor); highlightColor = array.getColor(R.styleable.MaterialSpinner_ms_highlightColor, defaultHighlightColor); errorColor = array.getColor(R.styleable.MaterialSpinner_ms_errorColor, defaultErrorColor); - disabledColor = context.getResources().getColor(R.color.disabled_color); + disabledColor = array.getColor(R.styleable.MaterialSpinner_ms_disabledColor, defaultDisabledColor); error = array.getString(R.styleable.MaterialSpinner_ms_error); hint = array.getString(R.styleable.MaterialSpinner_ms_hint); hintColor = array.getColor(R.styleable.MaterialSpinner_ms_hintColor, baseColor); diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index be6bff3..e1920b9 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -1,9 +1,10 @@ - - - + + + +