转载请标明出处 :http://blog.csdn.net/qq_19986309 尊重他人劳动成果~ 谢谢
今天给大家实现一个 带清除按钮 和 晃动效果的 自定义 EditText 常常大家写登录 注册按钮 可能是需要用到的, 好了 废话不多说 直接上效果图
这样的效果还是不错的 也是比较实用 不管在哪里的注册登录都用得着 下面贴下代码
public class ClearWriteEditText extends EditText implements View.OnFocusChangeListener , TextWatcher {
/**
* 删除按钮的引用
*/
private Drawable mClearDrawable;
public ClearWriteEditText(Context context) {
this(context,null);
}
public ClearWriteEditText(Context context, AttributeSet attrs) {
//这里构造方法也很重要,不加这个很多属性不能再XML里面定义
this(context, attrs, android.R.attr.editTextStyle);
}
public ClearWriteEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mClearDrawable = getResources().getDrawable(R.mipmap.search_clear_pressed_write);
mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
setClearIconVisible(false);
this.setOnFocusChangeListener(this);
this.addTextChangedListener(this);
}
/**
* 当输入框里面内容发生变化的时候回调的方法
*/
@Override
public void onTextChanged(CharSequence s, int start, int count, int after) {
setClearIconVisible(s.length() > 0);
}
/**
* 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去
* @param visible
*/
protected void setClearIconVisible(boolean visible) {
Drawable right = visible ? mClearDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0],
getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
}
/**
* 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件
* 当我们按下的位置 在 EditText的宽度 - 图标到控件右边的间距 - 图标的宽度 和
* EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向没有考虑
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (getCompoundDrawables()[2] != null) {
if (event.getAction() == MotionEvent.ACTION_UP) {
boolean touchable = event.getX() > (getWidth()
- getPaddingRight() - mClearDrawable.getIntrinsicWidth())
&& (event.getX() < ((getWidth() - getPaddingRight())));
if (touchable) {
this.setText("");
}
}
}
return super.onTouchEvent(event);
}
/**
* 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏
*/
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
setClearIconVisible(getText().length() > 0);
} else {
setClearIconVisible(false);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
/**
* 设置晃动动画
*/
public void setShakeAnimation(){this.setAnimation(shakeAnimation(3));}
/**
* 晃动动画
* @param counts 半秒钟晃动多少下
* @return
*/
public static Animation shakeAnimation(int counts){
Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
translateAnimation.setInterpolator(new CycleInterpolator(counts));
translateAnimation.setDuration(500);
return translateAnimation;
}
public Drawable getClearDrawable() {
return mClearDrawable;
}
public void setClearDrawable(Drawable mClearDrawable) {
this.mClearDrawable = mClearDrawable;
}
}
我们看到自定义的 带晃动清除效果的 EditText 当然是集成 EditText 删除按钮的 图片 在 init 方法里面自己设置 资源 getResources().getDrawable 自己想定义成什么样式皆可
然后别的都比较简单 有注释 值得一想的是 清除的话点击按钮 直接把 setText(""); 给空字符串 可以不可以 不过我没有去试过 然后用法就很简单了 跟普通的 EditText 没有差别
附上截图一张
最后说下晃动的效果 大家见如下代码:
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_regist:
userAcc = mUserName.getText().toString().trim();
pwd = mPassword.getText().toString().trim();
confirmpass = mPassword_two.getText().toString().trim();
if (TextUtils.isEmpty(userAcc)) {
Message msg = Message.obtain();
msg.what = USERNAMEISNULL;
mHandler.sendMessage(msg);
return;
}
这里是发送消息 如果 用户名为空的情况 再见下面代码:
private final int USERNAMEISNULL = 0;
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case USERNAMEISNULL:
mUserName.setShakeAnimation();
NToast.shortToast(mContext, R.string.username_null_text);
break;
}
}
};
这里是处理消息 我们看到弹了 一个 Toast 提示用户名 不能为空 和 执行 晃动效果动画 但是目前一直困扰我的是 不管是 开线程 和 Handler发消息 还是直接在UI线程 去执行动画效果 都不好用 但是得出一个结论 跟大家分享一下 每次判断 EditText 比如为 空 toast 弹了 但是 动画 必须 你手指去点击 EditText 或者文字有增删 才会触发这个动画效果 不然不会执行 在这里如果有朋友 get 了 这个blog 解决了 这个问题 还请一定留言评论或者发邮件告诉笔者, 不胜感激!