package com.mm.android.deviceaddmodule.mobilecommon.widget; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.text.Editable; import android.text.TextWatcher; import android.util.AttributeSet; import android.view.ActionMode; import android.view.ActionMode.Callback; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnFocusChangeListener; import android.view.inputmethod.EditorInfo; import android.widget.EditText; import com.mm.android.deviceaddmodule.R; import com.mm.android.deviceaddmodule.mobilecommon.utils.StringUtils; public class ClearEditText extends android.support.v7.widget.AppCompatEditText implements OnFocusChangeListener, TextWatcher,Callback { // EditTxtå³ä¾§çš„åˆ é™¤æŒ‰é’® private Drawable mClearDrawable; private boolean hasFous; private int mLimitedLen = -1; private boolean mbPWDFilter = false; private boolean mbUnregFilter = false; private TextWatcher mTextWatcher; private ITextChangeListener mListener; private IFocusChangeListener mFocusListener; private boolean isVisiableClearIcon = true; public interface IFocusChangeListener{ public void onClearTextFocusChange(View v, boolean hasFocus); } public interface ITextChangeListener { public void afterChanged(EditText v, Editable s); public void beforeChanged(EditText v, CharSequence s, int start, int count, int after); public void onTextChanged(EditText v, CharSequence text, int start, int lengthBefore, int lengthAfter); } public void setClearTextFocusChange(IFocusChangeListener listener){ mFocusListener = listener; } @SuppressWarnings("unchecked") public void setTextChangeListener(ITextChangeListener l) { mListener = l; } public void setTextWathcher(TextWatcher textWatcher) { mTextWatcher = textWatcher; } public ClearEditText(Context context) { this(context, null); } public ClearEditText(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.editTextStyle); } public ClearEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { // 获å–EditTextçš„DrawableRight, å‡å¦‚没有设置我们就使用默认的图片,获å–å›¾ç‰‡çš„é¡ºåºæ˜¯å·¦ä¸Šå³ä¸‹ï¼ˆ0.1.2.3) mClearDrawable = getCompoundDrawables()[2]; if (mClearDrawable == null) { mClearDrawable = getResources().getDrawable(R.drawable.ic_password_clear); } mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight()); //å¼€å¯å®‰å…¨ç›‘控 setFilterTouchesWhenObscured(true); // 默认设置éšè—å›¾æ ‡ setClearIconVisible(false); // 设置焦点改å˜çš„ç›‘å¬ setOnFocusChangeListener(this); // 设置输入框里é¢å†…容å‘生改å˜çš„ç›‘å¬ addTextChangedListener(this); // 默认设置ä¸èƒ½copy // setCopyAble(false); } /** * @说明: isInnerWidth, isInnerHeight为true, è§¦æ‘¸ç‚¹åœ¨åˆ é™¤å›¾æ ‡ä¹‹å†…ï¼Œåˆ™è§†ä¸ºç‚¹å‡»äº†åˆ é™¤å›¾æ ‡ event.getX() 获å–相应自身左上角的Xåæ ‡ * event.getY() 获å–相应自身左上角的Yåæ ‡ getWidth() èŽ·å–æŽ§ä»¶çš„å®½åº¦ getHight() èŽ·å–æŽ§ä»¶çš„é«˜åº¦ getTotalPaddingRight() * 获å–åˆ é™¤å›¾æ ‡å·¦è¾¹è¾¹ç¼˜åˆ°æŽ§ä»¶å³è¾¹ç¼˜çš„è·ç¦» getPaddubgRight() 获å–åˆ é™¤å›¾æ ‡å³è¾¹è¾¹ç¼˜åˆ°æŽ§ä»¶å³è¾¹ç¼˜çš„è·ç¦» isInnerWidth: getWidth() - * getTotalPaddingRight() è®¡ç®—åˆ é™¤å›¾æ ‡å·¦è¾¹ç¼˜åˆ°æŽ§ä»¶å·¦è¾¹ç¼˜çš„è·ç¦» getWidth() - getPaddingRight() * è®¡ç®—åˆ é™¤å›¾æ ‡å³è¾¹ç¼˜åˆ°æŽ§ä»¶å·¦è¾¹ç¼˜çš„è·ç¦» isInnerHight: `distance åˆ é™¤å›¾æ ‡é¡¶éƒ¨è¾¹ç¼˜å¸¦æŽ§ä»¶é¡¶éƒ¨è¾¹ç¼˜çš„è·ç¦» distance + height * åˆ é™¤å›¾æ ‡åº•éƒ¨è¾¹ç¼˜åˆ°æŽ§ä»¶é¡¶éƒ¨è¾¹ç¼˜çš„è·ç¦» */ @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { if (mClearDrawable != null) { int x = (int) event.getX(); int y = (int) event.getY(); Rect rect = mClearDrawable.getBounds(); int height = rect.height(); int distance = (getHeight() - height) / 2; boolean isInnerWidth = x > (getWidth() - getTotalPaddingRight()) && x < (getWidth() - getPaddingRight()); boolean isInnerHeight = y > distance && y < (distance + height); if (isInnerHeight && isInnerWidth) { setText(""); } } } return super.onTouchEvent(event); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } public void setClearIconVisible(boolean visible) { if(visible && !isVisiableClearIcon){ return; } Drawable right = visible ? mClearDrawable : null; setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], right, getCompoundDrawables()[3]); } public boolean isVisiableClearIcon() { return isVisiableClearIcon; } public void setVisiableClearIcon(boolean visiableClearIcon) { isVisiableClearIcon = visiableClearIcon; } @Override public void onFocusChange(View v, boolean hasFocus) { this.hasFous = hasFocus; if (hasFocus) { setClearIconVisible(getText().length() > 0); } else { setClearIconVisible(false); } if(mFocusListener != null){ mFocusListener.onClearTextFocusChange(v, hasFocus); } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { removeTextChangedListener(this); if (mListener != null) { mListener.beforeChanged(this, s, start, count, after); } if (mTextWatcher != null) { mTextWatcher.beforeTextChanged(s, start, count, after); } addTextChangedListener(this); } @Override public void afterTextChanged(Editable s) { removeTextChangedListener(this); filter(s); if (mListener != null) { mListener.afterChanged(this, s); } if (mTextWatcher != null) { mTextWatcher.afterTextChanged(s); } addTextChangedListener(this); } @Override public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { removeTextChangedListener(this); if (mListener != null) { mListener.onTextChanged(this, text, start, lengthBefore, lengthAfter); } if (mTextWatcher != null) { mTextWatcher.onTextChanged(text, start, lengthBefore, lengthAfter); } addTextChangedListener(this); if (hasFous) { setClearIconVisible(getText().toString().length() > 0); } } /* 功能区 */ private void filter(Editable s) { String str = s.toString(); int indexStart = ClearEditText.this.getSelectionStart(); if (mbPWDFilter) { str = StringUtils.strPwdFilter(str); int iDelLen = s.length() - str.length(); if (iDelLen > 0) { ClearEditText.this.setText(str); if (indexStart - iDelLen >= 0 && indexStart - iDelLen <= str.length()) { ClearEditText.this.setSelection(indexStart - iDelLen); indexStart -= iDelLen; } } } else if (mbUnregFilter) { str = StringUtils.strFilter(s.toString()); int iDelLen = s.length() - str.length(); if (iDelLen > 0) { ClearEditText.this.setText(str); if (indexStart - iDelLen >= 0 && indexStart - iDelLen <= str.length()) { ClearEditText.this.setSelection(indexStart - iDelLen); indexStart -= iDelLen; } } } limitLenght(str, indexStart); } /** * 设置最大输入长度,1ä¸ªä¸æ–‡è®¡ä¸¤ä¸ªè‹±æ–‡ï¼Œä¸”自动å±è”½ä¸è§„则å—符 * * @param maxlen */ public void setMaxLenth(int maxlen) { if (maxlen > 0) { mLimitedLen = maxlen; } else { mLimitedLen = 20; } } /** * 输入框是å¦å¯ä»¥å¤åˆ¶|粘贴(该方法åªé€‚åˆAPI11下的) * * @param copyAble */ public void setCopyAble(boolean copyAble) { this.setLongClickable(copyAble); if(copyAble){ setCustomSelectionActionModeCallback(null); }else{ setCustomSelectionActionModeCallback(this); setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); } } /** * 是å¦é™åˆ¶ç‰¹æ®Šå—符输入 * * @param enbale */ public void setUnregFilterEnbale(boolean enbale) { mbUnregFilter = enbale; } /** * 是å¦é™ä¸æ–‡åŠåˆ¶ç‰¹æ®Šå—符输入,常用于密ç 输入 * * @param enbale */ public void setCHFilterEnbale(boolean enbale) { mbPWDFilter = enbale; } private void limitLenght(String str, int indexStart) { if (mLimitedLen > 0) { boolean bFlag = false; if (calcultateLength(str) > mLimitedLen) { bFlag = true; } while (calcultateLength(str) > mLimitedLen) { if (indexStart > 0 && indexStart <= str.length()) { str = str.substring(0, indexStart - 1) + str.substring(indexStart, str.length()); } else { str = str.substring(0, str.length() - 1); } indexStart = indexStart - 1; } if (bFlag) { setText(str); if (indexStart >= 0 && indexStart <= str.length()) { setSelection(indexStart); } } } } private int calcultateLength(CharSequence c) { int len = 0; for (int i = 0; i < c.length(); i++) { int tmp = c.charAt(i); if (tmp > 0 && tmp < 127) { len++; } else { len += 2; } } return len; } @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return false; } @Override public void onDestroyActionMode(ActionMode mode) { } }