推送对接,分辨率适配
This commit is contained in:
2
verification-view/src/main/AndroidManifest.xml
Normal file
2
verification-view/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.tuo.customview" />
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.tuo.customview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
|
||||
import androidx.appcompat.widget.AppCompatEditText;
|
||||
|
||||
/**
|
||||
* author slimvan
|
||||
* email: slimvan@163.com
|
||||
* date 2018/7/24.
|
||||
* desc: 重写InputConnection 监听返回键
|
||||
*/
|
||||
|
||||
public class PwdEditText extends AppCompatEditText {
|
||||
private TInputConnection inputConnection;
|
||||
|
||||
public PwdEditText(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public PwdEditText(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public PwdEditText(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init(){
|
||||
inputConnection = new TInputConnection(null,true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当输入法和EditText建立连接的时候会通过这个方法返回一个InputConnection。
|
||||
* 我们需要代理这个方法的父类方法生成的InputConnection并返回我们自己的代理类。
|
||||
* */
|
||||
@Override
|
||||
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||
inputConnection.setTarget(super.onCreateInputConnection(outAttrs));
|
||||
return inputConnection;
|
||||
}
|
||||
|
||||
public void setBackSpaceListener(TInputConnection.BackspaceListener backSpaceLisetener){
|
||||
inputConnection.setBackspaceListener(backSpaceLisetener);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.tuo.customview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
|
||||
/**
|
||||
*
|
||||
* 作者:Tuo on 2018/4/13 16:35
|
||||
* 邮箱:839539179@qq.com
|
||||
*/
|
||||
|
||||
public class PwdTextView extends AppCompatTextView {
|
||||
|
||||
|
||||
private float radius;
|
||||
|
||||
private boolean hasPwd;
|
||||
|
||||
public PwdTextView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public PwdTextView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public PwdTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
if (hasPwd) {
|
||||
// 画一个黑色的圆
|
||||
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
paint.setColor(Color.WHITE);
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);
|
||||
}else {
|
||||
// 占位白色的圆
|
||||
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
paint.setColor(getResources().getColor(R.color.circle_bg));
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void clearPwd() {
|
||||
this.hasPwd = false;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
public void drawPwd(float radius) {
|
||||
this.hasPwd = true;
|
||||
if (radius == 0) {
|
||||
this.radius = getWidth() / 4;
|
||||
} else {
|
||||
this.radius = radius;
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void drawPwdBg(float radius) {
|
||||
if (radius == 0) {
|
||||
this.radius = getWidth() / 4;
|
||||
} else {
|
||||
this.radius = radius;
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.tuo.customview;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.view.inputmethod.InputConnectionWrapper;
|
||||
|
||||
/**
|
||||
* author slimvan
|
||||
* email: slimvan@163.com
|
||||
* date 2018/7/24.
|
||||
* desc: 参考https://blog.csdn.net/frained/article/details/78880579
|
||||
*/
|
||||
|
||||
public class TInputConnection extends InputConnectionWrapper {
|
||||
|
||||
private BackspaceListener mBackspaceListener;
|
||||
|
||||
/**
|
||||
* Initializes a wrapper.
|
||||
* <p>
|
||||
* <p><b>Caveat:</b> Although the system can accept {@code (InputConnection) null} in some
|
||||
* places, you cannot emulate such a behavior by non-null {@link InputConnectionWrapper} that
|
||||
* has {@code null} in {@code target}.</p>
|
||||
*
|
||||
* @param target the {@link InputConnection} to be proxied.
|
||||
* @param mutable set {@code true} to protect this object from being reconfigured to target
|
||||
* another {@link InputConnection}. Note that this is ignored while the target is {@code null}.
|
||||
*/
|
||||
public TInputConnection(InputConnection target, boolean mutable) {
|
||||
super(target, mutable);
|
||||
}
|
||||
|
||||
public interface BackspaceListener {
|
||||
/**
|
||||
* @return true 代表消费了这个事件
|
||||
* */
|
||||
boolean onBackspace();
|
||||
}
|
||||
|
||||
/**
|
||||
* 当软键盘删除文本之前,会调用这个方法通知输入框,我们可以重写这个方法并判断是否要拦截这个删除事件。
|
||||
* 在谷歌输入法上,点击退格键的时候不会调用{@link #sendKeyEvent(KeyEvent event)},
|
||||
* 而是直接回调这个方法,所以也要在这个方法上做拦截;
|
||||
* */
|
||||
@Override
|
||||
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
|
||||
if(mBackspaceListener != null){
|
||||
if(mBackspaceListener.onBackspace()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.deleteSurroundingText(beforeLength, afterLength);
|
||||
}
|
||||
|
||||
public void setBackspaceListener(BackspaceListener backspaceListener) {
|
||||
this.mBackspaceListener = backspaceListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当在软件盘上点击某些按钮(比如退格键,数字键,回车键等),该方法可能会被触发(取决于输入法的开发者),
|
||||
* 所以也可以重写该方法并拦截这些事件,这些事件就不会被分发到输入框了
|
||||
* */
|
||||
@Override
|
||||
public boolean sendKeyEvent(KeyEvent event) {
|
||||
if( event.getKeyCode() == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN){
|
||||
if(mBackspaceListener != null && mBackspaceListener.onBackspace()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.sendKeyEvent(event);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
package com.tuo.customview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.Editable;
|
||||
import android.text.InputFilter;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
||||
/**
|
||||
* description: 自定义view 验证码 输入框
|
||||
* Created by Jack on 2017/6/2.
|
||||
* 邮箱:839539179@qq.com
|
||||
*/
|
||||
|
||||
public class VerificationCodeView extends RelativeLayout {
|
||||
|
||||
private LinearLayout containerEt;
|
||||
|
||||
private PwdEditText et;
|
||||
// 输入框数量
|
||||
private int mEtNumber;
|
||||
// 输入框的宽度
|
||||
private int mEtWidth;
|
||||
//输入框分割线
|
||||
private Drawable mEtDividerDrawable;
|
||||
//输入框文字颜色
|
||||
private int mEtTextColor;
|
||||
//输入框文字大小
|
||||
private float mEtTextSize;
|
||||
//输入框获取焦点时背景
|
||||
private Drawable mEtBackgroundDrawableFocus;
|
||||
//输入框没有焦点时背景
|
||||
private Drawable mEtBackgroundDrawableNormal;
|
||||
//是否是密码模式
|
||||
private boolean mEtPwd;
|
||||
//密码模式时圆的半径
|
||||
private float mEtPwdRadius;
|
||||
|
||||
//存储TextView的数据 数量由自定义控件的属性传入
|
||||
private PwdTextView[] mPwdTextViews;
|
||||
|
||||
private MyTextWatcher myTextWatcher = new MyTextWatcher();
|
||||
|
||||
|
||||
public VerificationCodeView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public VerificationCodeView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public VerificationCodeView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
//初始化 布局和属性
|
||||
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
LayoutInflater.from(context).inflate(R.layout.layout_identifying_code, this);
|
||||
containerEt = (LinearLayout) this.findViewById(R.id.container_et);
|
||||
et = (PwdEditText) this.findViewById(R.id.et);
|
||||
|
||||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.VerificationCodeView, defStyleAttr, 0);
|
||||
mEtNumber = typedArray.getInteger(R.styleable.VerificationCodeView_icv_et_number, 1);
|
||||
mEtWidth = typedArray.getDimensionPixelSize(R.styleable.VerificationCodeView_icv_et_width, 42);
|
||||
mEtDividerDrawable = typedArray.getDrawable(R.styleable.VerificationCodeView_icv_et_divider_drawable);
|
||||
mEtTextSize = typedArray.getDimensionPixelSize(R.styleable.VerificationCodeView_icv_et_text_size, (int) sp2px(16, context));
|
||||
mEtTextColor = typedArray.getColor(R.styleable.VerificationCodeView_icv_et_text_color, Color.BLACK);
|
||||
mEtBackgroundDrawableFocus = typedArray.getDrawable(R.styleable.VerificationCodeView_icv_et_bg_focus);
|
||||
mEtBackgroundDrawableNormal = typedArray.getDrawable(R.styleable.VerificationCodeView_icv_et_bg_normal);
|
||||
mEtPwd = typedArray.getBoolean(R.styleable.VerificationCodeView_icv_et_pwd, false);
|
||||
mEtPwdRadius = typedArray.getDimensionPixelSize(R.styleable.VerificationCodeView_icv_et_pwd_radius, 0);
|
||||
//释放资源
|
||||
typedArray.recycle();
|
||||
|
||||
|
||||
// 当xml中未配置时 这里进行初始配置默认图片
|
||||
if (mEtDividerDrawable == null) {
|
||||
mEtDividerDrawable = context.getResources().getDrawable(R.drawable.shape_divider_identifying);
|
||||
}
|
||||
|
||||
if (mEtBackgroundDrawableFocus == null) {
|
||||
mEtBackgroundDrawableFocus = context.getResources().getDrawable(R.drawable.shape_icv_et_bg_focus);
|
||||
}
|
||||
|
||||
if (mEtBackgroundDrawableNormal == null) {
|
||||
mEtBackgroundDrawableNormal = context.getResources().getDrawable(R.drawable.shape_icv_et_bg_normal);
|
||||
}
|
||||
|
||||
initUI();
|
||||
}
|
||||
|
||||
// 初始UI
|
||||
private void initUI() {
|
||||
initTextViews(getContext(), mEtNumber, mEtWidth, mEtDividerDrawable, mEtTextSize, mEtTextColor);
|
||||
initEtContainer(mPwdTextViews);
|
||||
setListener();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// 设置当 高为 warpContent 模式时的默认值 为 50dp
|
||||
int mHeightMeasureSpec = heightMeasureSpec;
|
||||
|
||||
int heightMode = MeasureSpec.getMode(mHeightMeasureSpec);
|
||||
if (heightMode == MeasureSpec.AT_MOST) {
|
||||
mHeightMeasureSpec = MeasureSpec.makeMeasureSpec((int) dp2px(50, getContext()), MeasureSpec.EXACTLY);
|
||||
}
|
||||
|
||||
super.onMeasure(widthMeasureSpec, mHeightMeasureSpec);
|
||||
}
|
||||
|
||||
|
||||
//初始化TextView
|
||||
private void initTextViews(Context context, int etNumber, int etWidth, Drawable etDividerDrawable, float etTextSize, int etTextColor) {
|
||||
// 设置 editText 的输入长度
|
||||
et.setCursorVisible(false);//将光标隐藏
|
||||
et.setFilters(new InputFilter[]{new InputFilter.LengthFilter(etNumber)}); //最大输入长度
|
||||
// 设置分割线的宽度
|
||||
if (etDividerDrawable != null) {
|
||||
etDividerDrawable.setBounds(0, 0, etDividerDrawable.getMinimumWidth(), etDividerDrawable.getMinimumHeight());
|
||||
containerEt.setDividerDrawable(etDividerDrawable);
|
||||
}
|
||||
mPwdTextViews = new PwdTextView[etNumber];
|
||||
|
||||
for (int i = 0; i < mPwdTextViews.length; i++) {
|
||||
PwdTextView textView = new PwdTextView(context);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, etTextSize);
|
||||
textView.setTextColor(etTextColor);
|
||||
textView.setWidth(etWidth);
|
||||
textView.setHeight(etWidth);
|
||||
if (mEtPwd) {
|
||||
textView.drawPwdBg(mEtPwdRadius);
|
||||
}
|
||||
if (i == 0) {
|
||||
textView.setBackgroundDrawable(mEtBackgroundDrawableFocus);
|
||||
} else {
|
||||
textView.setBackgroundDrawable(mEtBackgroundDrawableNormal);
|
||||
}
|
||||
textView.setGravity(Gravity.CENTER);
|
||||
|
||||
textView.setFocusable(false);
|
||||
|
||||
mPwdTextViews[i] = textView;
|
||||
}
|
||||
}
|
||||
|
||||
//初始化存储TextView 的容器
|
||||
private void initEtContainer(TextView[] mTextViews) {
|
||||
for (TextView mTextView : mTextViews) {
|
||||
containerEt.addView(mTextView);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setListener() {
|
||||
// 监听输入内容
|
||||
et.addTextChangedListener(myTextWatcher);
|
||||
|
||||
// 监听删除按键
|
||||
et.setOnKeyListener(new OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
onKeyDelete();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 给TextView 设置文字
|
||||
private void setText(String inputContent) {
|
||||
|
||||
for (int i = 0; i < mPwdTextViews.length; i++) {
|
||||
PwdTextView tv = mPwdTextViews[i];
|
||||
if (tv.getText().toString().trim().equals("")) {
|
||||
if (mEtPwd) {
|
||||
tv.drawPwd(mEtPwdRadius);
|
||||
}
|
||||
tv.setText(inputContent);
|
||||
// 添加输入完成的监听
|
||||
if (inputCompleteListener != null) {
|
||||
inputCompleteListener.inputComplete();
|
||||
}
|
||||
tv.setBackgroundDrawable(mEtBackgroundDrawableNormal);
|
||||
if (i < mEtNumber - 1) {
|
||||
mPwdTextViews[i + 1].setBackgroundDrawable(mEtBackgroundDrawableFocus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 监听删除
|
||||
private void onKeyDelete() {
|
||||
for (int i = mPwdTextViews.length - 1; i >= 0; i--) {
|
||||
PwdTextView tv = mPwdTextViews[i];
|
||||
if (!tv.getText().toString().trim().equals("")) {
|
||||
if (mEtPwd) {
|
||||
tv.clearPwd();
|
||||
}
|
||||
tv.setText("");
|
||||
// 添加删除完成监听
|
||||
tv.setBackgroundDrawable(mEtBackgroundDrawableNormal);
|
||||
if (i < mEtNumber - 1) {
|
||||
mPwdTextViews[i + 1].setBackgroundDrawable(mEtBackgroundDrawableFocus);
|
||||
}
|
||||
// 添加输入完成的监听
|
||||
if (inputCompleteListener != null) {
|
||||
inputCompleteListener.inputComplete();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取输入文本
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public String getInputContent() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (TextView tv : mPwdTextViews) {
|
||||
buffer.append(tv.getText().toString().trim());
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除输入内容
|
||||
*/
|
||||
public void clearInputContent() {
|
||||
for (int i = 0; i < mPwdTextViews.length; i++) {
|
||||
if (i == 0) {
|
||||
mPwdTextViews[i].setBackgroundDrawable(mEtBackgroundDrawableFocus);
|
||||
} else {
|
||||
mPwdTextViews[i].setBackgroundDrawable(mEtBackgroundDrawableNormal);
|
||||
}
|
||||
if (mEtPwd) {
|
||||
mPwdTextViews[i].clearPwd();
|
||||
}
|
||||
mPwdTextViews[i].setText("");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置输入框个数
|
||||
*
|
||||
* @param etNumber
|
||||
*/
|
||||
public void setEtNumber(int etNumber) {
|
||||
this.mEtNumber = etNumber;
|
||||
et.removeTextChangedListener(myTextWatcher);
|
||||
containerEt.removeAllViews();
|
||||
initUI();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取输入的位数
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public int getEtNumber() {
|
||||
return mEtNumber;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置是否是密码模式 默认不是
|
||||
*
|
||||
* @param isPwdMode
|
||||
*/
|
||||
public void setPwdMode(boolean isPwdMode) {
|
||||
this.mEtPwd = isPwdMode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取输入的EditText 用于外界设置键盘弹出
|
||||
*
|
||||
* @return EditText
|
||||
*/
|
||||
public EditText getEditText() {
|
||||
return et;
|
||||
}
|
||||
|
||||
// 输入完成 和 删除成功 的监听
|
||||
private InputCompleteListener inputCompleteListener;
|
||||
|
||||
public void setInputCompleteListener(InputCompleteListener inputCompleteListener) {
|
||||
this.inputCompleteListener = inputCompleteListener;
|
||||
}
|
||||
|
||||
|
||||
public interface InputCompleteListener {
|
||||
void inputComplete();
|
||||
|
||||
void deleteContent();
|
||||
}
|
||||
|
||||
|
||||
public float dp2px(float dpValue, Context context) {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
|
||||
dpValue, context.getResources().getDisplayMetrics());
|
||||
}
|
||||
|
||||
public float sp2px(float spValue, Context context) {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
|
||||
spValue, context.getResources().getDisplayMetrics());
|
||||
}
|
||||
|
||||
|
||||
private class MyTextWatcher implements TextWatcher {
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
String inputStr = editable.toString();
|
||||
if (!TextUtils.isEmpty(inputStr)) {
|
||||
|
||||
String[] strArray = inputStr.split("");
|
||||
|
||||
for (int i = 0; i < strArray.length; i++) {
|
||||
|
||||
// 不能大于输入框个数
|
||||
if (i > mEtNumber) {
|
||||
break;
|
||||
}
|
||||
setText(strArray[i]);
|
||||
et.setText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<size
|
||||
android:width="6dp"
|
||||
android:height="6dp" />
|
||||
<solid android:color="#00000000" />
|
||||
</shape>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#F2F2F2" />
|
||||
<!-- 大小 -->
|
||||
<size
|
||||
android:width="25dp"
|
||||
android:height="25dp" /><!-- 宽度和高度 -->
|
||||
<corners android:radius="2dp" />
|
||||
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#A6D8EB" />
|
||||
</shape>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#F2F2F2" />
|
||||
<!-- 大小 -->
|
||||
<size
|
||||
android:width="25dp"
|
||||
android:height="25dp" /><!-- 宽度和高度 -->
|
||||
<corners android:radius="2dp" />
|
||||
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#C7C7CD" />
|
||||
</shape>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container_et"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerInParent="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:showDividers="middle">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.tuo.customview.PwdEditText
|
||||
android:id="@+id/et"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/transparent"
|
||||
android:inputType="number" />
|
||||
|
||||
</RelativeLayout>
|
||||
24
verification-view/src/main/res/values/attrs.xml
Normal file
24
verification-view/src/main/res/values/attrs.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- 自定义验证码输入框-->
|
||||
<declare-styleable name="VerificationCodeView">
|
||||
<!--输入框的数量-->
|
||||
<attr name="icv_et_number" format="integer" />
|
||||
<!--输入框的宽度-->
|
||||
<attr name="icv_et_width" format="dimension|reference" />
|
||||
<!--输入框之间的分割线-->
|
||||
<attr name="icv_et_divider_drawable" format="reference" />
|
||||
<!--输入框文字颜色-->
|
||||
<attr name="icv_et_text_color" format="color|reference" />
|
||||
<!--输入框文字大小-->
|
||||
<attr name="icv_et_text_size" format="dimension|reference" />
|
||||
<!--输入框获取焦点时边框-->
|
||||
<attr name="icv_et_bg_focus" format="reference" />
|
||||
<!--输入框没有焦点时边框-->
|
||||
<attr name="icv_et_bg_normal" format="reference" />
|
||||
<!--是否是密码模式-->
|
||||
<attr name="icv_et_pwd" format="boolean" />
|
||||
<!--密码模式时,圆的半径-->
|
||||
<attr name="icv_et_pwd_radius" format="dimension|reference" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
6
verification-view/src/main/res/values/colors.xml
Normal file
6
verification-view/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<color name="circle_bg">#2a2c36</color>
|
||||
|
||||
</resources>
|
||||
3
verification-view/src/main/res/values/strings.xml
Normal file
3
verification-view/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">VerificationView</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user