MainActivity如下:
package cc.textview5;import android.os.Bundle;import android.text.TextUtils;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;import android.app.Activity;/** * Demo描述: * 自訂控制項實現帶清除功能的EditText * * 學習資料: * http://blog.csdn.net/xiaanming/article/details/11066685 * * Thank you very much */public class MainActivity extends Activity { private CleanableEditText mUserNameCleanableEditText; private CleanableEditText mPassWordCleanableEditText; private Button mLoginButton;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);init();}private void init(){mUserNameCleanableEditText=(CleanableEditText) findViewById(R.id.userNameEditText);mPassWordCleanableEditText=(CleanableEditText) findViewById(R.id.passwordEditText);mLoginButton=(Button) findViewById(R.id.loginButton);mLoginButton.setOnClickListener(new OnClickListenerImpl());} private class OnClickListenerImpl implements OnClickListener {@Overridepublic void onClick(View view) {if (TextUtils.isEmpty(mUserNameCleanableEditText.getText())) {mUserNameCleanableEditText.setShakeAnimation();Toast.makeText(MainActivity.this, "請輸入使用者名稱", Toast.LENGTH_SHORT).show();}if (TextUtils.isEmpty(mPassWordCleanableEditText.getText())) {mPassWordCleanableEditText.setShakeAnimation();Toast.makeText(MainActivity.this, "請輸入密碼", Toast.LENGTH_SHORT).show();}}}}
CleanableEditText如下:
package cc.textview5;import android.content.Context;import android.graphics.drawable.Drawable;import android.text.Editable;import android.text.TextWatcher;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.animation.Animation;import android.view.animation.CycleInterpolator;import android.view.animation.TranslateAnimation;import android.widget.EditText;/** * 在焦點變化時和輸入內容發生變化時均要判斷是否顯示右邊clean表徵圖 */public class CleanableEditText extends EditText { private Drawable mRightDrawable; private boolean isHasFocus;public CleanableEditText(Context context) {super(context);init();}public CleanableEditText(Context context, AttributeSet attrs) {super(context, attrs);init();}public CleanableEditText(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}private void init(){//getCompoundDrawables://Returns drawables for the left, top, right, and bottom borders.Drawable [] drawables=this.getCompoundDrawables();//取得right位置的Drawable//即我們在布局檔案中設定的android:drawableRight mRightDrawable=drawables[2]; //設定焦點變化的監聽 this.setOnFocusChangeListener(new FocusChangeListenerImpl()); //設定EditText文字變化的監聽 this.addTextChangedListener(new TextWatcherImpl()); //初始化時讓右邊clean表徵圖不可見 setClearDrawableVisible(false);}/** * 當手指抬起的位置在clean的表徵圖的地區 * 我們將此視為進行清除操作 * getWidth():得到控制項的寬度 * event.getX():抬起時的座標(改座標是相對於控制項本身而言的) * getTotalPaddingRight():clean的表徵圖左邊緣至控制項右邊緣的距離 * getPaddingRight():clean的表徵圖右邊緣至控制項右邊緣的距離 * 於是: * getWidth() - getTotalPaddingRight()表示: * 控制項左邊到clean的表徵圖左邊緣的地區 * getWidth() - getPaddingRight()表示: * 控制項左邊到clean的表徵圖右邊緣的地區 * 所以這兩者之間的地區剛好是clean的表徵圖的地區 */@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_UP:boolean isClean =(event.getX() > (getWidth() - getTotalPaddingRight()))&& (event.getX() < (getWidth() - getPaddingRight()));if (isClean) {setText("");}break;default:break;}return super.onTouchEvent(event);}private class FocusChangeListenerImpl implements OnFocusChangeListener{@Overridepublic void onFocusChange(View v, boolean hasFocus) { isHasFocus=hasFocus; if (isHasFocus) { boolean isVisible=getText().toString().length()>=1; setClearDrawableVisible(isVisible);} else { setClearDrawableVisible(false);}}}//當輸入結束後判斷是否顯示右邊clean的表徵圖 private class TextWatcherImpl implements TextWatcher{@Overridepublic void afterTextChanged(Editable s) { boolean isVisible=getText().toString().length()>=1; setClearDrawableVisible(isVisible);}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count,int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before,int count) {} } //隱藏或者顯示右邊clean的表徵圖protected void setClearDrawableVisible(boolean isVisible) {Drawable rightDrawable;if (isVisible) {rightDrawable = mRightDrawable;} else {rightDrawable = null;}//使用代碼設定該控制項left, top, right, and bottom處的表徵圖setCompoundDrawables(getCompoundDrawables()[0],getCompoundDrawables()[1], rightDrawable,getCompoundDrawables()[3]);} // 顯示一個動畫,以提示使用者輸入public void setShakeAnimation() {this.setAnimation(shakeAnimation(5));}//CycleTimes動畫重複的次數public Animation shakeAnimation(int CycleTimes) {Animation translateAnimation = new TranslateAnimation(0, 10, 0, 10);translateAnimation.setInterpolator(new CycleInterpolator(CycleTimes));translateAnimation.setDuration(1000);return translateAnimation;}}
main.xml如下: