1 package com.lixu.clearedittext; 2 3 4 import android.app.Activity; 5 import android.os.Bundle; 6 import android.text.TextUtils; 7 import android.view.View; 8 import android.view.View.OnClickListener; 9 import android.widget.Button;10 import android.widget.Toast;11 12 public class MainActivity extends Activity {13 private Toast mToast;14 15 @Override16 protected void onCreate(Bundle savedInstanceState) {17 super.onCreate(savedInstanceState);18 setContentView(R.layout.activity_main);19 20 final ClearEditText username = (ClearEditText) findViewById(R.id.username);21 final ClearEditText password = (ClearEditText) findViewById(R.id.password);22 23 ((Button) findViewById(R.id.login)).setOnClickListener(new OnClickListener() {24 25 @Override26 public void onClick(View v) {27 if(TextUtils.isEmpty(username.getText())){28 //设置晃动29 username.setShakeAnimation();30 //设置提示31 showToast("用户名不能为空");32 return;33 }34 35 if(TextUtils.isEmpty(password.getText())){36 password.setShakeAnimation();37 showToast("密码不能为空");38 return;39 }40 }41 });42 }43 44 /**45 * 显示Toast消息46 * @param msg47 */48 private void showToast(String msg){49 if(mToast == null){50 mToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);51 }else{52 mToast.setText(msg);53 }54 mToast.show();55 }56 57 58 }
1 package com.lixu.clearedittext; 2 3 4 import android.content.Context; 5 import android.graphics.drawable.Drawable; 6 import android.text.Editable; 7 import android.text.TextWatcher; 8 import android.util.AttributeSet; 9 import android.view.MotionEvent; 10 import android.view.View; 11 import android.view.View.OnFocusChangeListener; 12 import android.view.animation.Animation; 13 import android.view.animation.CycleInterpolator; 14 import android.view.animation.TranslateAnimation; 15 import android.widget.EditText; 16 17 public class ClearEditText extends EditText implements 18 OnFocusChangeListener, TextWatcher { 19 /** 20 * 删除按钮的引用 21 */ 22 private Drawable mClearDrawable; 23 /** 24 * 控件是否有焦点 25 */ 26 private boolean hasFoucs; 27 28 public ClearEditText(Context context) { 29 this(context, null); 30 } 31 32 public ClearEditText(Context context, AttributeSet attrs) { 33 //这里构造方法也很重要,不加这个很多属性不能再XML里面定义 34 this(context, attrs, android.R.attr.editTextStyle); 35 } 36 37 public ClearEditText(Context context, AttributeSet attrs, int defStyle) { 38 super(context, attrs, defStyle); 39 init(); 40 } 41 42 43 private void init() { 44 //获取EditText的DrawableRight,假如没有设置我们就使用默认的图片,右边位置图片 45 mClearDrawable = getCompoundDrawables()[2]; 46 if (mClearDrawable == null) { 47 // throw new NullPointerException("You can add drawableRight attribute in XML"); 48 mClearDrawable = getResources().getDrawable(R.drawable.delete_selector); 49 } 50 51 mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight()); 52 //默认设置隐藏图标 53 setClearIconVisible(false); 54 //设置焦点改变的监听 55 setOnFocusChangeListener(this); 56 //设置输入框里面内容发生改变的监听 57 addTextChangedListener(this); 58 } 59 60 61 /** 62 * 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件 63 * 当我们按下的位置 在 EditText的宽度 - 图标到控件右边的间距 - 图标的宽度 和 64 * EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向就没有考虑 65 */ 66 @Override 67 public boolean onTouchEvent(MotionEvent event) { 68 if (event.getAction() == MotionEvent.ACTION_UP) { 69 if (getCompoundDrawables()[2] != null) { 70 71 boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight()) 72 && (event.getX() < ((getWidth() - getPaddingRight()))); 73 74 if (touchable) { 75 this.setText(""); 76 } 77 } 78 } 79 80 return super.onTouchEvent(event); 81 } 82 83 /** 84 * 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏 85 */ 86 @Override 87 public void onFocusChange(View v, boolean hasFocus) { 88 this.hasFoucs = hasFocus; 89 if (hasFocus) { 90 setClearIconVisible(getText().length() > 0); 91 } else { 92 setClearIconVisible(false); 93 } 94 } 95 96 97 /** 98 * 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去 99 * @param visible100 */101 protected void setClearIconVisible(boolean visible) { 102 Drawable right = visible ? mClearDrawable : null; 103 setCompoundDrawables(getCompoundDrawables()[0], 104 getCompoundDrawables()[1], right, getCompoundDrawables()[3]); 105 } 106 107 108 /**109 * 当输入框里面内容发生变化的时候回调的方法110 */111 @Override 112 public void onTextChanged(CharSequence s, int start, int count, 113 int after) { 114 if(hasFoucs){115 setClearIconVisible(s.length() > 0);116 }117 } 118 119 @Override 120 public void beforeTextChanged(CharSequence s, int start, int count, 121 int after) { 122 123 } 124 125 @Override 126 public void afterTextChanged(Editable s) { 127 128 } 129 130 131 /**132 * 设置晃动动画133 */134 public void setShakeAnimation(){135 this.setAnimation(shakeAnimation(5));136 }137 138 139 /**140 * 晃动动画141 * @param counts 1秒钟晃动多少下142 * @return143 */144 public static Animation shakeAnimation(int counts){145 Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);146 translateAnimation.setInterpolator(new CycleInterpolator(counts));147 translateAnimation.setDuration(1000);148 return translateAnimation;149 }150 151 152 }
xml文件:
1 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 2 xmlns:tools="http://schemas.android.com/tools" 3 3 android:layout_width="match_parent" 4 4 android:layout_height="match_parent" 5 5 android:background="#95CAE4"> 6 6 7 7 8 8 <com.lixu.clearedittext.ClearEditText 9 9 android:id="@+id/username"10 10 android:layout_marginTop="60dp"11 11 android:layout_width="fill_parent"12 12 android:background="@drawable/login_edittext_bg" 13 13 android:drawableLeft="@drawable/icon_user"14 14 android:layout_marginLeft="10dip"15 15 android:layout_marginRight="10dip"16 16 android:singleLine="true"17 17 android:drawableRight="@drawable/delete_selector"18 18 android:hint="输入用户名"19 19 android:layout_height="wrap_content" >20 20 21 21 </com.lixu.clearedittext.ClearEditText>22 22 23 23 <com.lixu.clearedittext.ClearEditText24 24 android:id="@+id/password"25 25 android:layout_marginLeft="10dip"26 26 android:layout_marginRight="10dip"27 27 android:layout_marginTop="10dip"28 28 android:drawableLeft="@drawable/account_icon"29 29 android:hint="输入密码"30 30 android:singleLine="true"31 31 android:password="true"32 32 android:drawableRight="@drawable/delete_selector"33 33 android:layout_width="fill_parent"34 34 android:layout_height="wrap_content"35 35 android:layout_below="@id/username"36 36 android:background="@drawable/login_edittext_bg" >37 37 </com.lixu.clearedittext.ClearEditText>38 38 39 39 <Button40 40 android:id="@+id/login"41 41 android:layout_width="fill_parent"42 42 android:layout_height="wrap_content"43 43 android:layout_marginLeft="10dip"44 44 android:layout_marginRight="10dip"45 45 android:background="@drawable/login_button_bg"46 46 android:textSize="18sp"47 47 android:textColor="@android:color/white"48 48 android:layout_below="@+id/password"49 49 android:layout_marginTop="25dp"50 50 android:text="登录" />51 51 52 52 </RelativeLayout>
1 <?xml version="1.0" encoding="utf-8"?>2 <selector3 xmlns:android="http://schemas.android.com/apk/res/android">4 <item android:state_pressed="true" android:drawable="@drawable/search_clear_pressed" />5 <item android:drawable="@drawable/search_clear_normal" />6 </selector>
1 <?xml version="1.0" encoding="UTF-8"?>2 <selector xmlns:android="http://schemas.android.com/apk/res/android">3 4 <item android:drawable="@drawable/btn_style_one_pressed" android:state_pressed="true"></item>5 <item android:drawable="@drawable/btn_style_one_focused" android:state_focused="true"></item>6 <item android:drawable="@drawable/btn_style_one_normal"></item>7 8 </selector>
1 <?xml version="1.0" encoding="UTF-8"?>2 <selector xmlns:android="http://schemas.android.com/apk/res/android">3 <item android:state_focused="true" android:drawable="@drawable/login_edit_pressed"></item>4 <item android:state_pressed="true" android:drawable="@drawable/login_edit_pressed"></item>5 <item android:drawable="@drawable/login_edit_normal"></item>6 </selector>
运行效果图: