1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
| public class PassWordView extends LinearLayout {
private int defaultSize = 6; private PasswordCallback passwordCallback; interface PassWordCallback { void complete(String password) }
public void setPasswordCallback(PasswordCallback passwordCallback) { this.passwordCallback = passwordCallback; } private boolean showFocusShape = true; private EditText editText;
public PassWordView(@NonNull Context context) { super(context); init(); }
public PassWordView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); }
public PassWordView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); }
public void clearPassWord() { editText.setText(null); }
@SuppressLint("CheckResult") private void init() { editText = new EditText(getContext()); editText.setTextSize(12f); editText.setLayoutParams(new FrameLayout.LayoutParams(1, ViewGroup.LayoutParams.WRAP_CONTENT)); editText.setCursorVisible(false); editText.setBackgroundDrawable(null); editText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD); addView(editText); editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(defaultSize)}); setOnClickListener(v -> { if (editText.requestFocus()) { InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) { imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); } } });
double space = SizeUtils.dp2px(6); for (int i = 0; i < defaultSize; i++) { TextView textView = (TextView) LayoutInflater.from(getContext()).inflate(R.layout.single_pwd_editext, null); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1); layoutParams.setMarginStart((int) (space * i / defaultSize)); layoutParams.setMarginEnd((int) (space * (defaultSize - i - 1) / defaultSize)); addView(textView, layoutParams); } editText.setOnFocusChangeListener((v, hasFocus) -> { if (!showFocusShape) { return; } for (int i = 1; i < getChildCount(); i++) { getChildAt(i).setBackgroundResource(hasFocus ? R.drawable.shape_editext_border_green_2r : R.drawable.shape_edittext_border_background_with_error); } }); editText.addTextChangedListener(new 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) { TextView childAt = (TextView) getChildAt(start + 1); if (before == 0) { childAt.setText("●"); } else { childAt.setText(""); } if (!TextUtils.isEmpty(s) && s.length() == defaultSize) { if (passwordCallback != null) { try { passwordCallback.complete(s.toString()); } catch (Exception e) { e.printStackTrace(); } } } }
@Override public void afterTextChanged(Editable s) {
} }); }
public String getPwd() { return editText.getText().toString(); }
public void setFocusShape(boolean showFocusShape) { this.showFocusShape = showFocusShape; }
public static class SquareTextView extends AppCompatTextView {
public SquareTextView(Context context) { super(context); }
public SquareTextView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); if (widthMode == MeasureSpec.UNSPECIFIED) { throw new RuntimeException("mode is UNSPECIFIED"); } else { setMeasuredDimension(widthSize, widthSize); } } } }
|