From c158f81795ae8e83d55e5f7f81b3970b221acc4c Mon Sep 17 00:00:00 2001 From: yj Date: Mon, 12 Jun 2017 11:05:25 +0800 Subject: [PATCH] =?UTF-8?q?Action:alter=20Description:=E4=BF=AE=E6=94=B9Ve?= =?UTF-8?q?rcodeEditText=E6=8E=A7=E4=BB=B6=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=B8=8B=E5=88=92=E7=BA=BF=E5=BC=82=E5=B8=B8=E3=80=81height?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E9=80=82=E9=85=8D=E3=80=81=E5=AE=BD=E5=BA=A6?= =?UTF-8?q?=E5=B7=A6=E5=8F=B3=E7=BC=A9=E8=BF=9B=E9=97=AE=E9=A2=98;=20TODO:?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A0=E6=B3=95=E8=BE=93=E5=85=A5bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 9 +- app/src/main/res/layout/activity_main.xml | 51 +++- app/src/main/res/values/colors.xml | 8 +- vcedittext-lib/build.gradle | 36 ++- .../jkb/vcedittext/VerificationAction.java | 62 +++++ .../vcedittext/VerificationCodeEditText.java | 262 ++++++++++++++++++ vcedittext-lib/src/main/res/values/attrs.xml | 12 + 7 files changed, 410 insertions(+), 30 deletions(-) create mode 100644 vcedittext-lib/src/main/java/com/jkb/vcedittext/VerificationAction.java create mode 100644 vcedittext-lib/src/main/java/com/jkb/vcedittext/VerificationCodeEditText.java create mode 100644 vcedittext-lib/src/main/res/values/attrs.xml diff --git a/app/build.gradle b/app/build.gradle index ee51bc7..d7f809b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,7 +11,6 @@ android { targetSdkVersion rootProject.ext.targetSdkVersion versionCode appVerCode versionName appVerName - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } compileOptions { sourceCompatibility rootProject.ext.sourceCompatibilityVersion @@ -55,10 +54,6 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) - compule deps.appcompat_v7 - testCompile deps.junit + compile deps.appcompat_v7 + compile project(':vcedittext-lib') } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index b33a055..bbd4bb1 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,13 +1,54 @@ + android:background="@android:color/white" + android:orientation="vertical"> - + android:layout_margin="20dp" + android:inputType="number" + android:text="123" + android:textColor="@color/colorPrimary" + android:textSize="40sp" + app:bottomLineHeight="2dp" + app:bottomLineNormalColor="@color/gravy_light" + app:bottomLineSelectedColor="@color/colorAccent" + app:figures="4" + app:selectedBackgroundColor="@color/colorPrimary_alpha33" + app:verCodeMargin="10dp" /> + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 3ab3e9c..a3f74ef 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,6 +1,8 @@ - #3F51B5 - #303F9F - #FF4081 + #bd3e27 + #702314 + #bd3e27 + #64e42604 + #999999 diff --git a/vcedittext-lib/build.gradle b/vcedittext-lib/build.gradle index 6b30ee2..5d40b80 100644 --- a/vcedittext-lib/build.gradle +++ b/vcedittext-lib/build.gradle @@ -1,17 +1,27 @@ apply plugin: 'com.android.library' +apply plugin: 'com.novoda.bintray-release' + +def appVerCode = 1 +def appVerName = "1.0.0" + +publish { + userOrg = 'jkb' + groupId = 'com.justkiddingbaby' + artifactId = 'vercodeedittext' + publishVersion = appVerName + desc = 'An Android vercode edittext.(一个安卓验证码输入框)' + website = 'https://github.com/YangJing96/VercodeEditText' +} android { - compileSdkVersion 25 - buildToolsVersion "25.0.3" + compileSdkVersion Integer.parseInt(COMPILE_SDK_VERSION) + buildToolsVersion BUILDTOOLS_VERSION defaultConfig { - minSdkVersion 12 - targetSdkVersion 25 - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - + minSdkVersion Integer.parseInt(MIN_SDK_VERSION) + targetSdkVersion Integer.parseInt(TARGET_SDK_VERSION) + versionCode appVerCode + versionName appVerName } buildTypes { release { @@ -19,13 +29,9 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + lintOptions { abortOnError false } } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { - exclude group: 'com.android.support', module: 'support-annotations' - }) - compile 'com.android.support:appcompat-v7:25.3.1' - testCompile 'junit:junit:4.12' + compile "com.android.support:appcompat-v7:${SUPPORT_LIB_VERSION}" } diff --git a/vcedittext-lib/src/main/java/com/jkb/vcedittext/VerificationAction.java b/vcedittext-lib/src/main/java/com/jkb/vcedittext/VerificationAction.java new file mode 100644 index 0000000..31a766f --- /dev/null +++ b/vcedittext-lib/src/main/java/com/jkb/vcedittext/VerificationAction.java @@ -0,0 +1,62 @@ +package com.jkb.vcedittext; + +import android.support.annotation.ColorRes; + +/** + * 填写验证码支持的Action + * Created by yj on 2017/5/11. + */ + +interface VerificationAction { + + /** + * 设置位数 + */ + void setFigures(int figures); + + /** + * 设置验证码之间的间距 + */ + void setVerCodeMargin(int margin); + + /** + * 设置底部选中状态的颜色 + */ + void setBottomSelectedColor(@ColorRes int bottomSelectedColor); + + /** + * 设置底部未选中状态的颜色 + */ + void setBottomNormalColor(@ColorRes int bottomNormalColor); + + /** + * 设置选择的背景色 + */ + void setSelectedBackgroundColor(@ColorRes int selectedBackground); + + /** + * 设置底线的高度 + */ + void setBottomLineHeight(int bottomLineHeight); + + /** + * 设置当验证码变化时候的监听器 + */ + void setOnVerificationCodeChangedListener(OnVerificationCodeChangedListener listener); + + /** + * 验证码变化时候的监听事件 + */ + interface OnVerificationCodeChangedListener { + + /** + * 当验证码变化的时候 + */ + void onVerCodeChanged(CharSequence s, int start, int before, int count); + + /** + * 输入完毕后的回调 + */ + void onInputCompleted(CharSequence s); + } +} diff --git a/vcedittext-lib/src/main/java/com/jkb/vcedittext/VerificationCodeEditText.java b/vcedittext-lib/src/main/java/com/jkb/vcedittext/VerificationCodeEditText.java new file mode 100644 index 0000000..c53b1af --- /dev/null +++ b/vcedittext-lib/src/main/java/com/jkb/vcedittext/VerificationCodeEditText.java @@ -0,0 +1,262 @@ +package com.jkb.vcedittext; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.support.annotation.ColorRes; +import android.support.v4.content.ContextCompat; +import android.text.Editable; +import android.text.TextPaint; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.WindowManager; + + +/** + * 验证码的EditText + * Created by yj on 2017/6/12. + */ + +public class VerificationCodeEditText extends android.support.v7.widget.AppCompatEditText implements + VerificationAction, TextWatcher { + + private int mFigures;//需要输入的位数 + private int mVerCodeMargin;//验证码之间的间距 + private int mBottomSelectedColor;//底部选中的颜色 + private int mBottomNormalColor;//未选中的颜色 + private float mBottomLineHeight;//底线的高度 + private int mSelectedBackgroundColor;//选中的背景颜色 + + private OnVerificationCodeChangedListener onCodeChangedListener; + private int mCurrentPosition = 0; + private int mEachRectLength = 0;//每个矩形的边长 + private Paint mSelectedBackgroundPaint; + private Paint mNormalBackgroundPaint; + private Paint mBottomSelectedPaint; + private Paint mBottomNormalPaint; + + public VerificationCodeEditText(Context context) { + this(context, null); + } + + public VerificationCodeEditText(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public VerificationCodeEditText(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initAttrs(attrs); + setBackgroundColor(ContextCompat.getColor(context, android.R.color.transparent));//防止出现下划线 + initPaint(); + super.addTextChangedListener(this); + } + + /** + * 初始化paint + */ + private void initPaint() { + mSelectedBackgroundPaint = new Paint(); + mSelectedBackgroundPaint.setColor(mSelectedBackgroundColor); + mNormalBackgroundPaint = new Paint(); + mNormalBackgroundPaint.setColor(getColor(android.R.color.transparent)); + + mBottomSelectedPaint = new Paint(); + mBottomNormalPaint = new Paint(); + mBottomSelectedPaint.setColor(mBottomSelectedColor); + mBottomNormalPaint.setColor(mBottomNormalColor); + mBottomSelectedPaint.setStrokeWidth(mBottomLineHeight); + mBottomNormalPaint.setStrokeWidth(mBottomLineHeight); + } + + /** + * 初始化Attrs + */ + private void initAttrs(AttributeSet attrs) { + TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.VerCodeEditText); + mFigures = ta.getInteger(R.styleable.VerCodeEditText_figures, 4); + mVerCodeMargin = (int) ta.getDimension(R.styleable.VerCodeEditText_verCodeMargin, 0); + mBottomSelectedColor = ta.getColor(R.styleable.VerCodeEditText_bottomLineSelectedColor, + getCurrentTextColor()); + mBottomNormalColor = ta.getColor(R.styleable.VerCodeEditText_bottomLineNormalColor, + getColor(android.R.color.darker_gray)); + mBottomLineHeight = ta.getDimension(R.styleable.VerCodeEditText_bottomLineHeight, + dp2px(5)); + mSelectedBackgroundColor = ta.getColor(R.styleable.VerCodeEditText_selectedBackgroundColor, + getColor(android.R.color.darker_gray)); + ta.recycle(); + } + + + @Override + final public void setCursorVisible(boolean visible) { + super.setCursorVisible(false);//隐藏光标的显示 + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int widthResult = 0, heightResult = 0; + //最终的宽度 + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + if (widthMode == MeasureSpec.EXACTLY) { + widthResult = widthSize; + } else { + widthResult = getScreenWidth(getContext()); + } + //每个矩形形的宽度 + mEachRectLength = (widthResult - (mVerCodeMargin * (mFigures - 1))) / mFigures; + //最终的高度 + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + if (heightMode == MeasureSpec.EXACTLY) { + heightResult = heightSize; + } else { + heightResult = mEachRectLength; + } + setMeasuredDimension(widthResult, heightResult); + } + + @Override + protected void onDraw(Canvas canvas) { + mCurrentPosition = getText().length(); + int width = mEachRectLength - getPaddingLeft() - getPaddingRight(); + int height = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); + for (int i = 0; i < mFigures; i++) { + canvas.save(); + int start = width * i + i * mVerCodeMargin; + int end = width + start; + //画一个矩形 + if (i == mCurrentPosition) {//选中的下一个状态 + canvas.drawRect(start, 0, end, height, mSelectedBackgroundPaint); + } else { + canvas.drawRect(start, 0, end, height, mNormalBackgroundPaint); + } + canvas.restore(); + } + //绘制文字 + String value = getText().toString(); + for (int i = 0; i < value.length(); i++) { + canvas.save(); + int start = width * i + i * mVerCodeMargin; + float x = start + width / 2; + TextPaint paint = getPaint(); + paint.setTextAlign(Paint.Align.CENTER); + paint.setColor(getCurrentTextColor()); + Paint.FontMetrics fontMetrics = paint.getFontMetrics(); + float baseline = (height - fontMetrics.bottom + fontMetrics.top) / 2 + - fontMetrics.top; + canvas.drawText(String.valueOf(value.charAt(i)), x, baseline, paint); + canvas.restore(); + } + //绘制底线 + for (int i = 0; i < mFigures; i++) { + canvas.save(); + float lineY = height - mBottomLineHeight / 2; + int start = width * i + i * mVerCodeMargin; + int end = width + start; + if (i < mCurrentPosition) { + canvas.drawLine(start, lineY, end, lineY, mBottomSelectedPaint); + } else { + canvas.drawLine(start, lineY, end, lineY, mBottomNormalPaint); + } + canvas.restore(); + } + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + mCurrentPosition = getText().length(); + postInvalidate(); + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + mCurrentPosition = getText().length(); + postInvalidate(); + if (onCodeChangedListener != null) { + onCodeChangedListener.onVerCodeChanged(getText(), start, before, count); + } + } + + @Override + public void afterTextChanged(Editable s) { + mCurrentPosition = getText().length(); + postInvalidate(); + if (getText().length() == mFigures) { + if (onCodeChangedListener != null) { + onCodeChangedListener.onInputCompleted(getText()); + } + } else if (getText().length() > mFigures) { + getText().delete(mFigures, getText().length()); + } + } + + @Override + public void setFigures(int figures) { + mFigures = figures; + postInvalidate(); + } + + @Override + public void setVerCodeMargin(int margin) { + mVerCodeMargin = margin; + postInvalidate(); + } + + @Override + public void setBottomSelectedColor(@ColorRes int bottomSelectedColor) { + mBottomSelectedColor = getColor(bottomSelectedColor); + postInvalidate(); + } + + @Override + public void setBottomNormalColor(@ColorRes int bottomNormalColor) { + mBottomSelectedColor = getColor(bottomNormalColor); + postInvalidate(); + } + + @Override + public void setSelectedBackgroundColor(@ColorRes int selectedBackground) { + mSelectedBackgroundColor = getColor(selectedBackground); + postInvalidate(); + } + + @Override + public void setBottomLineHeight(int bottomLineHeight) { + this.mBottomLineHeight = bottomLineHeight; + postInvalidate(); + } + + @Override + public void setOnVerificationCodeChangedListener(OnVerificationCodeChangedListener listener) { + this.onCodeChangedListener = listener; + } + + /** + * 返回颜色 + */ + private int getColor(@ColorRes int color) { + return ContextCompat.getColor(getContext(), color); + } + + /** + * dp转px + */ + private int dp2px(int dp) { + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, + getResources().getDisplayMetrics()); + } + + /** + * 获取手机屏幕的宽度 + */ + static int getScreenWidth(Context context) { + DisplayMetrics metrics = new DisplayMetrics(); + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + wm.getDefaultDisplay().getMetrics(metrics); + return metrics.widthPixels; + } +} diff --git a/vcedittext-lib/src/main/res/values/attrs.xml b/vcedittext-lib/src/main/res/values/attrs.xml new file mode 100644 index 0000000..475e93a --- /dev/null +++ b/vcedittext-lib/src/main/res/values/attrs.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file