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 @Override 16 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 @Override 26 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 msg 47 */ 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 visible 100 */ 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 * @return 143 */ 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.ClearEditText 24 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 <Button 40 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 <selector 3 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>
运行效果图: