
package com.yoostar.huayuVOD.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class PasswordView extends View {
private Paint mPaint;
private int mPwdEncryptionType;
private int mPwdEncryptionColor;
private boolean isDrawPwdEncryption;
private int mBoxType;
private int mInputBoxBgColor;
private int mBoxWidth = 40;
private int mBoxHeight = 40;
private boolean isInutState;
private boolean isShowInputCursor;
private boolean isDrawInputCursor;
private int inputCursorColor;
private int mTextSize;
private int mBoxStrokeWidth;
private Context mContext;
private String inputText;
private static final String TAG = "PasswordView";
public void setInputText(String inputText) {
this.inputText = inputText;
}
public void setPwdEncryptionType(int pwdEncryptionType) {
mPwdEncryptionType = pwdEncryptionType;
}
public void setPwdEncryptionColor(int pwdEncryptionColor) {
mPwdEncryptionColor = pwdEncryptionColor;
}
public void setBoxType(int boxType) {
mBoxType = boxType;
}
public void setInputBoxBgColor(int inputBoxBgColor) {
mInputBoxBgColor = inputBoxBgColor;
}
public void setBoxWidth(int boxWidth) {
mBoxWidth = boxWidth;
}
public void setBoxHeight(int boxHeight) {
mBoxHeight = boxHeight;
}
public void setShowInputCursor(boolean showInputCursor) {
isShowInputCursor = showInputCursor;
}
public void setInputCursorColor(int inputCursorColor) {
this.inputCursorColor = inputCursorColor;
}
public void setTextSize(int textSize) {
mTextSize = textSize;
}
public void setBoxStrokeWidth(int boxStrokeWidth) {
mBoxStrokeWidth = boxStrokeWidth;
}
public PasswordView(Context context) {
this(context, null);
}
public PasswordView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mContext = context;
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(mBoxStrokeWidth);
mPaint.setPathEffect(new CornerPathEffect(1));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
int width = 0;
int height = 0;
if (modeWidth == MeasureSpec.EXACTLY) {
width = sizeWidth;
}
else if (modeWidth == MeasureSpec.AT_MOST) {
width = Math.min(sizeWidth, mBoxWidth);
} else {
width = mBoxWidth;
}
if (modeHeight == MeasureSpec.EXACTLY) {
height = sizeHeight;
} else if (modeHeight == MeasureSpec.AT_MOST) {
height = Math.min(mBoxHeight, sizeHeight);
} else {
height = mBoxHeight;
}
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
drawInputBox(canvas);
drawInputCursor(canvas);
drawPwdType(canvas);
}
private void drawPwdType(Canvas canvas) {
if (isDrawPwdEncryption) {
Log.i(TAG, "drawPwdType: ");
mPaint.setColor(Color.parseColor("#4DFFFFFF"));
mPaint.setStyle(Paint.Style.FILL);
switch (mPwdEncryptionType) {
case 0:
canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, 8, mPaint);
break;
case 1:
mPaint.setTextSize(getMeasuredWidth() / 2 + 10);
float stringWidth = mPaint.measureText("*");
float baseY = (getMeasuredHeight() / 2 - ((mPaint.descent() + mPaint.ascent()) / 2)) + stringWidth / 3;
float baseX = getMeasuredWidth() / 2 - stringWidth / 2;
canvas.drawText("x", baseX, baseY, mPaint);
break;
case 2:
mPaint.setTextSize(mTextSize);
float inputTextWidth = mPaint.measureText(inputText);
float baseInputTextY = (getMeasuredHeight() / 2 - ((mPaint.descent() + mPaint.ascent()) / 2)) + inputTextWidth / 5;
float baseInputTextX = getMeasuredWidth() / 2 - inputTextWidth / 2;
canvas.drawText(inputText, baseInputTextX, baseInputTextY, mPaint);
break;
default:
break;
}
}
}
private void drawInputCursor(Canvas canvas) {
if (isDrawInputCursor && isShowInputCursor) {
int lineHeight = getMeasuredWidth() / 2 - 5;
lineHeight = lineHeight < 0 ? getMeasuredWidth() / 2 : lineHeight;
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.parseColor("#FFFFFF"));
canvas.drawLine(getMeasuredWidth() / 2, getMeasuredHeight() / 2 - lineHeight / 2, getMeasuredWidth() / 2, getMeasuredHeight() / 2 + lineHeight / 2, mPaint);
}
}
private void drawInputBox(Canvas canvas) {
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.parseColor("#4475AE"));
switch (mBoxType) {
case 1:
canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, getMeasuredWidth() / 2 - 5, mPaint);
break;
case 2:
canvas.drawLine(0, getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight(), mPaint);
break;
default:
RectF rectF = new RectF(0, 9, getMeasuredWidth(), getMeasuredHeight());
canvas.drawRoundRect(rectF, 6, 6, mPaint);
}
}
public void drawInputPwd() {
removeCallbacks(flashCursorRunnable);
isShowInputCursor = false;
isDrawPwdEncryption = true;
invalidate();
}
public void clearAllPwd() {
removeCallbacks(flashCursorRunnable);
isShowInputCursor = false;
isDrawPwdEncryption = false;
invalidate();
}
public void showInputStatus() {
isShowInputCursor = true;
isDrawPwdEncryption = false;
post(flashCursorRunnable);
}
Runnable flashCursorRunnable = new Runnable() {
@Override
public void run() {
isDrawInputCursor = !isDrawInputCursor;
invalidate();
postDelayed(this, 800);
}
};
}
package com.yoostar.huayuVOD.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;
import com.yoostar.huayuVOD.R;
import com.yoostar.huayuVOD.utils.Logger;
import java.util.ArrayList;
import java.util.List;
public class PasswordLayout extends LinearLayout {
private Context mContext;
private int mRemindLineColor;
private int mInputTextColor;
private static final String TAG = "PasswordLayout";
private int mBoxDrawType = 0;
private int mShowPassType = 0;
private int mBoxWidth = 40;
private int mBoxHeight = 40;
private int mDrawTxtSize = 18;
private int mCurIndex ;
private int mBoxCount = 4;
private int mDrawBoxLineSize = 4;
private int mInterval;
private List<String> mPasswordList;
private PasswordLayout.onPasswordChangeListener mPwdChangeListener;
private StringBuffer mPassString;
public PasswordLayout(Context context) {
this(context, null);
}
public PasswordLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initPassword(context, attrs);
}
private void initPassword(Context context, AttributeSet attrs) {
mContext = context;
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PassWordLayoutStyle);
mRemindLineColor = ta.getResourceId(R.styleable.PassWordLayoutStyle_input_line_color, R.color.color_white);
mInputTextColor = ta.getResourceId(R.styleable.PassWordLayoutStyle_text_input_color, Color.parseColor("#3DA3FF"));
mBoxDrawType = ta.getInt(R.styleable.PassWordLayoutStyle_box_draw_type, 0);
mShowPassType = ta.getInt(R.styleable.PassWordLayoutStyle_pass_inputed_type, 0);
mBoxWidth = ta.getDimensionPixelOffset(R.styleable.PassWordLayoutStyle_item_width, 40);
mBoxHeight = ta.getDimensionPixelOffset(R.styleable.PassWordLayoutStyle_item_height, 40);
mDrawTxtSize = ta.getDimensionPixelOffset(R.styleable.PassWordLayoutStyle_draw_txt_size, 18);
mDrawBoxLineSize = ta.getDimensionPixelOffset(R.styleable.PassWordLayoutStyle_draw_box_line_size, 4);
mBoxCount = ta.getInt(R.styleable.PassWordLayoutStyle_passwordBox_count, 4);
mInterval = ta.getDimensionPixelOffset(R.styleable.PassWordLayoutStyle_interval_width, 5);
mPasswordList = new ArrayList<>();
ta.recycle();
setOnClickListener(mOnClickListener);
setOnFocusChangeListener(mOnFocusChangeListener);
setOnKeyListener(mOnKeyListener);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (getChildCount() == 0) {
if ((mBoxWidth * mBoxCount + (mBoxCount - 1) * mInterval) > getMeasuredWidth()) {
mBoxWidth = (getMeasuredWidth() - (mBoxCount - 1) * mInterval) / mBoxCount;
mBoxHeight = mBoxWidth;
}
addChildViews(getContext());
}
}
private void addChildViews(Context context) {
for (int i = 0; i < mBoxCount; i++) {
PasswordView passWordView = new PasswordView(context);
LayoutParams params = new LayoutParams(mBoxWidth, mBoxHeight);
if (i > 0) {
params.leftMargin = mInterval;
passWordView.setBoxHeight(mBoxHeight);
passWordView.setBoxWidth(mBoxWidth);
passWordView.setBoxStrokeWidth(10);
passWordView.setBoxType(0);
passWordView.setTextSize(10);
passWordView.setInputBoxBgColor(Color.parseColor("#4475AE"));
passWordView.setPwdEncryptionColor(Color.parseColor("#c8c8c8"));
passWordView.setPwdEncryptionType(0);
passWordView.setShowInputCursor(true);
}
addView(passWordView, params);
}
}
private OnClickListener mOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
setFocusable(true);
setFocusableInTouchMode(true);
requestFocus();
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(PasswordLayout.this, InputMethodManager.SHOW_IMPLICIT);
}
};
private OnFocusChangeListener mOnFocusChangeListener = new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
Logger.d(Logger._JN, "onFocusChange mCurIndex :%s ", mCurIndex);
if (hasFocus) {
if (mCurIndex == 4) {
removePwd();
}else {
drawFlashStatus(mCurIndex);
}
} else {
if (mCurIndex == 0){
clearInputStatus(mCurIndex);
}
}
}
};
private OnKeyListener mOnKeyListener = new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
addPwd(keyCode - 7 + " ");
return true;
}
if (keyCode == KeyEvent.KEYCODE_DEL) {
removePwd();
return true;
}
}
return false;
}
};
private void addPwd(String pwd) {
if (mPasswordList != null && mPasswordList.size() < mBoxCount) {
mPasswordList.add(pwd);
drawInputStatus(mCurIndex);
if (mCurIndex < mBoxCount ) {
drawFlashStatus(++mCurIndex);
}
}
if (mPasswordList.size() < mBoxCount) {
mPwdChangeListener.onChange(getPassString());
} else {
mPwdChangeListener.onFinished(getPassString());
}
}
private void removePwd() {
if (mPasswordList.size() == 0){
mPwdChangeListener.onNull();
}
if (mPasswordList != null && mPasswordList.size() > 0) {
mPasswordList.remove(mPasswordList.size() - 1);
clearInputStatus(mCurIndex);
if (mCurIndex >= 1) {
drawFlashStatus(--mCurIndex);
}
}
if (mPasswordList.size() != 0) {
mPwdChangeListener.onChange(getPassString());
}
}
public String getPassString() {
mPassString = new StringBuffer();
for (String i : mPasswordList) {
mPassString.append(i.trim());
}
Logger.d(Logger._JN, "getPassString :%s ", mPassString.toString());
return mPassString.toString();
}
private void drawInputStatus(int index) {
Logger.d(Logger._JN, "drawInputStatus :%s ", index);
PasswordView passwordView = (PasswordView) getChildAt(index);
passwordView.drawInputPwd();
}
public void drawFlashStatus(int index) {
if (index >= 4) {
return;
}
Logger.d(Logger._JN, "drawFlashStatus :%s ", index);
PasswordView passwordView = (PasswordView) getChildAt(index);
if (passwordView != null) {
passwordView.showInputStatus();
}
}
public void clearInputStatus(int index) {
if (index >= 4) {
return;
}
Logger.d(Logger._JN, "clearInputStatus :%s ", index);
PasswordView passwordView = (PasswordView) getChildAt(index);
passwordView.clearAllPwd();
}
public void setOnPasswordChangeListener(PasswordLayout.onPasswordChangeListener listener) {
mPwdChangeListener = listener;
}
public interface onPasswordChangeListener {
void onChange(String pwd);
void onFinished(String pwd);
void onNull();
}
}
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<!--密码输入layout-->
<declare-styleable name="PassWordLayoutStyle">
<attr name="box_input_color" format="reference"></attr>
<attr name="box_no_input_color" format="reference"></attr>
<attr name="input_line_color" format="reference"></attr>
<attr name="text_input_color" format="reference"></attr>
<attr name="interval_width" format="dimension"></attr>
<attr name="item_width" format="dimension"></attr>
<attr name="item_height" format="dimension"></attr>
<attr name="draw_txt_size" format="dimension"></attr>
<attr name="draw_box_line_size" format="dimension"></attr>
<attr name="is_show_input_line" format="boolean"></attr>
<attr name="pass_inputed_type">
<flag name="circle" value="0" />
<flag name="stars" value="1" />
<flag name="text" value="2" />
</attr>
<attr name="box_draw_type">
<flag name="rect" value="0" />
<flag name="circle" value="1" />
<flag name="line" value="2" />
</attr>
<attr name="pass_length">
<flag name="four" value="4" />
<flag name="six" value="6" />
<flag name="eight" value="8" />
</attr>
</declare-styleable>
</resources>