ClearEditTextView通過擴(kuò)展EditText漱抓,添加了右邊清除按鈕缺前、輸入數(shù)據(jù)不合法時(shí)可左右抖動(dòng)的功能会放。效果如下:
模擬登錄
整體的實(shí)現(xiàn)代碼如下:
public class ClearEditTextView extends EditText implements View.OnFocusChangeListener, TextWatcher {
//右邊的刪除按鈕
private Drawable mClearDrawable;
public ClearEditTextView(Context context) {
this(context, null);
}
public ClearEditTextView(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.editTextStyle);
}
public ClearEditTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mClearDrawable = getResources().getDrawable(R.drawable.clear);
//設(shè)置刪除按鈕的邊界
mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
//默認(rèn)隱藏刪除按鈕
setClearIcon(false);
//監(jiān)聽EditText焦點(diǎn)變化盖腿,以根據(jù)text長(zhǎng)度控制刪除按鈕的顯示、隱藏
setOnFocusChangeListener(this);
//監(jiān)聽文本內(nèi)容變化
addTextChangedListener(this);
}
/**
* 控制EditText右邊制刪除按鈕的顯示愈捅、隱藏
*/
private void setClearIcon(boolean isShow) {
Drawable rightDrawable = isShow ? mClearDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1],
rightDrawable, getCompoundDrawables()[3]);
}
/**
* 有焦點(diǎn)遏考,并文本長(zhǎng)度大于0則顯示刪除按鈕
*
* @param v
* @param hasFocus
*/
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
setClearIcon(getText().length() > 0);
} else {
setClearIcon(false);
}
}
/**
* 文本內(nèi)容變化時(shí)回調(diào)
* 當(dāng)文本長(zhǎng)度大于0時(shí)顯示刪除按鈕, 否則隱藏
*
* @param text
* @param start
* @param lengthBefore
* @param lengthAfter
*/
@Override
public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);
setClearIcon(text.length() > 0);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
/**
* 通過手指的觸摸位置模式刪除按鈕的點(diǎn)擊事件
*
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (getCompoundDrawables()[2] != null) {
if (event.getAction() == MotionEvent.ACTION_UP) {
boolean xTouchable = event.getX() > (getWidth() - getPaddingRight() - mClearDrawable.getIntrinsicWidth())
&& (event.getX() < (getWidth() - getPaddingRight()));
boolean yTouchable = event.getY() > (getHeight() - mClearDrawable.getIntrinsicHeight()) / 2
&& event.getY() < (getHeight() + mClearDrawable.getIntrinsicHeight()) / 2;
//清除文本
if (xTouchable && yTouchable) {
setText("");
}
}
}
return super.onTouchEvent(event);
}
/**
* EditText抖動(dòng)
*
* @param counts
* @return
*/
public void startShake(int counts) {
Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
translateAnimation.setInterpolator(new CycleInterpolator(counts));
translateAnimation.setDuration(500);
startAnimation(translateAnimation);
}
}
大致說一下流程蓝谨,首先給EditText添加addTextChangedListener
來監(jiān)聽輸入文本的變化灌具,如果EditText有焦點(diǎn)并文本長(zhǎng)度大于0則將EditText的drawableRight設(shè)置為刪除的圖片否則設(shè)置為空:
@Override
public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);
setClearIcon(text.length() > 0);
}
private void setClearIcon(boolean isShow) {
Drawable rightDrawable = isShow ? mClearDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1],
rightDrawable, getCompoundDrawables()[3]);
}
這樣刪除按鈕就添加好了。由于不能直接給添加的刪除按鈕綁定點(diǎn)擊事件譬巫,所以可以考慮通過重寫EditText的onTouchEvent
方法稽亏,如果手指的觸摸x、y坐標(biāo)在刪除圖片上則執(zhí)行刪除操作:
@Override
public boolean onTouchEvent(MotionEvent event) {
if (getCompoundDrawables()[2] != null) {
if (event.getAction() == MotionEvent.ACTION_UP) {
boolean xTouchable = event.getX() > (getWidth() - getPaddingRight() - mClearDrawable.getIntrinsicWidth())
&& (event.getX() < (getWidth() - getPaddingRight()));
boolean yTouchable = event.getY() > (getHeight() - mClearDrawable.getIntrinsicHeight()) / 2
&& event.getY() < (getHeight() + mClearDrawable.getIntrinsicHeight()) / 2;
//清除文本
if (xTouchable && yTouchable) {
setText("");
}
}
}
return super.onTouchEvent(event);
}
到這里刪除按鈕的邏輯就完成了缕题。關(guān)于左右抖動(dòng)的效果就是給EditText設(shè)置一個(gè)左右移動(dòng)的動(dòng)畫:
public void startShake(int counts) {
Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
translateAnimation.setInterpolator(new CycleInterpolator(counts));
translateAnimation.setDuration(500);
startAnimation(translateAnimation);
}
到這里一個(gè)簡(jiǎn)單的EditText擴(kuò)展就實(shí)現(xiàn)了截歉。
關(guān)于倒計(jì)時(shí)的功能可通過CountDownTimer
類方便的實(shí)現(xiàn):
mCountDownTimer = new CountDownTimer(long millisInFuture, long countDownInterval) {
@Override
public void onTick(long millisUntilFinished) {
//倒計(jì)時(shí)進(jìn)行中
}
@Override
public void onFinish() {
//倒計(jì)時(shí)結(jié)束
}
}
參數(shù)millisInFuture代表倒計(jì)時(shí)的總時(shí)長(zhǎng),countDownInterval代表時(shí)間間隔烟零,單位都是毫秒瘪松。通過CountDownTimer類的start()
和cancel()
方法可以開始和結(jié)束倒計(jì)時(shí)。