45ea71d4ec7fafcf0c2dee257e3302ff37c2b633.svn-base 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package com.hjq.widget;
  2. import android.annotation.SuppressLint;
  3. import android.content.Context;
  4. import android.graphics.drawable.Drawable;
  5. import android.support.v4.content.ContextCompat;
  6. import android.support.v4.graphics.drawable.DrawableCompat;
  7. import android.text.Editable;
  8. import android.text.InputType;
  9. import android.text.TextWatcher;
  10. import android.util.AttributeSet;
  11. import android.view.MotionEvent;
  12. import android.view.View;
  13. /**
  14. * Created by Android Studio.
  15. * User: zbb
  16. * Date: 2019/12/30
  17. * Describe: PasswordEditText 密码隐藏显示的EditText
  18. */
  19. public class PasswordEditText extends RegexEditText
  20. implements View.OnTouchListener,
  21. View.OnFocusChangeListener, TextWatcher {
  22. private static final int TYPE_VISIBLE = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
  23. private static final int TYPE_INVISIBLE = InputType.TYPE_TEXT_VARIATION_PASSWORD;
  24. private Drawable mCurrentDrawable;
  25. private Drawable mVisibleDrawable;
  26. private Drawable mInvisibleDrawable;
  27. private OnTouchListener mOnTouchListener;
  28. private OnFocusChangeListener mOnFocusChangeListener;
  29. public PasswordEditText(Context context) {
  30. super(context);
  31. }
  32. public PasswordEditText(Context context, AttributeSet attrs) {
  33. super(context, attrs);
  34. }
  35. public PasswordEditText(Context context, AttributeSet attrs, int defStyleAttr) {
  36. super(context, attrs, defStyleAttr);
  37. }
  38. @SuppressWarnings("all")
  39. @SuppressLint("ClickableViewAccessibility")
  40. @Override
  41. protected void initialize(Context context, AttributeSet attrs) {
  42. super.initialize(context, attrs);
  43. // Wrap the drawable so that it can be tinted pre Lollipop
  44. mVisibleDrawable = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.ic_input_show));
  45. mVisibleDrawable.setBounds(0, 0, mVisibleDrawable.getIntrinsicWidth(), mVisibleDrawable.getIntrinsicHeight());
  46. mInvisibleDrawable = DrawableCompat.wrap(ContextCompat.getDrawable(context, R.drawable.ic_input_hide));
  47. mInvisibleDrawable.setBounds(0, 0, mInvisibleDrawable.getIntrinsicWidth(), mInvisibleDrawable.getIntrinsicHeight());
  48. mCurrentDrawable = mVisibleDrawable;
  49. // 密码不可见
  50. addInputType(TYPE_INVISIBLE);
  51. if (getInputRegex() == null) {
  52. // 密码输入规则
  53. setInputRegex(REGEX_NONNULL);
  54. }
  55. setDrawableVisible(false);
  56. super.setOnTouchListener(this);
  57. super.setOnFocusChangeListener(this);
  58. super.addTextChangedListener(this);
  59. }
  60. private void setDrawableVisible(final boolean visible) {
  61. if (mCurrentDrawable.isVisible() == visible) {
  62. return;
  63. }
  64. mCurrentDrawable.setVisible(visible, false);
  65. final Drawable[] drawables = getCompoundDrawables();
  66. setCompoundDrawables(
  67. drawables[0],
  68. drawables[1],
  69. visible ? mCurrentDrawable : null,
  70. drawables[3]);
  71. }
  72. private void refreshDrawableStatus() {
  73. final Drawable[] drawables = getCompoundDrawables();
  74. setCompoundDrawables(
  75. drawables[0],
  76. drawables[1],
  77. mCurrentDrawable,
  78. drawables[3]);
  79. }
  80. @Override
  81. public void setOnFocusChangeListener(final OnFocusChangeListener onFocusChangeListener) {
  82. mOnFocusChangeListener = onFocusChangeListener;
  83. }
  84. @Override
  85. public void setOnTouchListener(final OnTouchListener onTouchListener) {
  86. mOnTouchListener = onTouchListener;
  87. }
  88. /**
  89. * {@link OnFocusChangeListener}
  90. */
  91. @Override
  92. public void onFocusChange(final View view, final boolean hasFocus) {
  93. if (hasFocus && getText() != null) {
  94. setDrawableVisible(getText().length() > 0);
  95. } else {
  96. setDrawableVisible(false);
  97. }
  98. if (mOnFocusChangeListener != null) {
  99. mOnFocusChangeListener.onFocusChange(view, hasFocus);
  100. }
  101. }
  102. /**
  103. * {@link OnTouchListener}
  104. */
  105. @Override
  106. public boolean onTouch(final View view, final MotionEvent motionEvent) {
  107. final int x = (int) motionEvent.getX();
  108. if (mCurrentDrawable.isVisible() && x > getWidth() - getPaddingRight() - mCurrentDrawable.getIntrinsicWidth()) {
  109. if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
  110. if (mCurrentDrawable == mVisibleDrawable) {
  111. mCurrentDrawable = mInvisibleDrawable;
  112. // 密码可见
  113. removeInputType(TYPE_INVISIBLE);
  114. addInputType(TYPE_VISIBLE);
  115. refreshDrawableStatus();
  116. } else if (mCurrentDrawable == mInvisibleDrawable) {
  117. mCurrentDrawable = mVisibleDrawable;
  118. // 密码不可见
  119. removeInputType(TYPE_VISIBLE);
  120. addInputType(TYPE_INVISIBLE);
  121. refreshDrawableStatus();
  122. }
  123. Editable editable = getText();
  124. if (editable != null) {
  125. setSelection(editable.toString().length());
  126. }
  127. }
  128. return true;
  129. }
  130. return mOnTouchListener != null && mOnTouchListener.onTouch(view, motionEvent);
  131. }
  132. /**
  133. * {@link TextWatcher}
  134. */
  135. @Override
  136. public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
  137. if (isFocused()) {
  138. setDrawableVisible(s.length() > 0);
  139. }
  140. }
  141. @Override
  142. public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
  143. @Override
  144. public void afterTextChanged(Editable s) {}
  145. }