Android一直没有提供类似于ios中自带清除效果的输入框(ios只要只要添加属性即可实现),所以在Android当中 想要实现此效果就需要使用自定义控件的方式实现。
思路:可以使用一个Linearlayout里面横向布局一个EditText和一个删除的图片,监听输入框的焦点和文字变化,设置图片的显隐和点击清除事件。但是这么做些弊端,首先增加了UI布局的层级结构不利于UI结构的优化而且可能会出现文字过长遮挡住图片的情况。所以采用自定义控件继承于EditText,使用getCompoundDrawables获得上下左右添加的图片,通过监听焦点变化和输入内容变化控制周围图片的显隐以及清除事件,(里面还附加了一个晃动的动画,例如当注册时如果输入为空可以进行晃动提示)。
原理十分简单直接上代码:
001.
public
class
ClearEditText
extends
EditText
implements
OnFocusChangeListener,TextWatcher {
002.
/**
003.
* 删除按钮的引用
004.
*/
005.
private
Drawable mClearDrawable;
006.
private
boolean
hasFoucs;
007.
008.
public
ClearEditText(Context context) {
009.
this
(context,
null
);
010.
}
011.
public
ClearEditText(Context context, AttributeSet attrs) {
012.
// 这里构造方法也很重要,不加这个很多属性不能再XML里面定义
013.
this
(context, attrs, android.R.attr.editTextStyle);
014.
}
015.
016.
public
ClearEditText(Context context, AttributeSet attrs,
int
defStyle) {
017.
super
(context, attrs, defStyle);
018.
init();
019.
}
020.
private
void
init() {
021.
// 获取EditText的DrawableRight,假如没有设置我们就使用默认的图片,2是获得右边的图片 顺序是左上右下(0,1,2,3,)
022.
mClearDrawable = getCompoundDrawables()[
2
];
023.
if
(mClearDrawable ==
null
) {
024.
// throw new
025.
// NullPointerException("You can add drawableRight attribute in XML");
026.
mClearDrawable = getResources().getDrawable(R.drawable.delete_selector);
027.
}
028.
029.
mClearDrawable.setBounds(
0
,
0
, mClearDrawable.getIntrinsicWidth(),mClearDrawable.getIntrinsicHeight());
030.
// 默认设置隐藏图标
031.
setClearIconVisible(
false
);
032.
// 设置焦点改变的监听
033.
setOnFocusChangeListener(
this
);
034.
// 设置输入框里面内容发生改变的监听
035.
addTextChangedListener(
this
);
036.
}
037.
038.
/**
039.
* 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件 当我们按下的位置 在 EditText的宽度 -
040.
* 图标到控件右边的间距 - 图标的宽度 和 EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向就没有考虑
041.
*/
042.
@Override
043.
public
boolean
onTouchEvent(MotionEvent event) {
044.
if
(event.getAction() == MotionEvent.ACTION_UP) {
045.
if
(getCompoundDrawables()[
2
] !=
null
) {
046.
boolean
touchable = event.getX() > (getWidth() - getTotalPaddingRight())&& (event.getX() < ((getWidth() - getPaddingRight())));
047.
if
(touchable) {
048.
this
.setText(
""
);
049.
}
050.
}
051.
}
052.
return
super
.onTouchEvent(event);
053.
}
054.
055.
/**
056.
* 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏
057.
*/
058.
@Override
059.
public
void
onFocusChange(View v,
boolean
hasFocus) {
060.
this
.hasFoucs = hasFocus;
061.
if
(hasFocus) {
062.
setClearIconVisible(getText().length() >
0
);
063.
}
else
{
064.
setClearIconVisible(
false
);
065.
}
066.
}
067.
068.
/**
069.
* 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去
070.
*
071.
* @param visible
072.
*/
073.
protected
void
setClearIconVisible(
boolean
visible) {
074.
Drawable right = visible ? mClearDrawable :
null
;
075.
setCompoundDrawables(getCompoundDrawables()[
0
],getCompoundDrawables()[
1
], right, getCompoundDrawables()[
3
]);
076.
}
077.
078.
/**
079.
* 当输入框里面内容发生变化的时候回调的方法
080.
*/
081.
@Override
082.
public
void
onTextChanged(CharSequence s,
int
start,
int
count,
int
after) {
083.
if
(hasFoucs) {
084.
setClearIconVisible(s.length() >
0
);
085.
}
086.
}
087.
088.
@Override
089.
public
void
beforeTextChanged(CharSequence s,
int
start,
int
count,
int
after) {
090.
091.
}
092.
093.
@Override
094.
public
void
afterTextChanged(Editable s) {
095.
096.
}
097.
098.
/**
099.
* 设置晃动动画
100.
*/
101.
public
void
setShakeAnimation() {
102.
this
.setAnimation(shakeAnimation(
5
));
103.
}
104.
105.
/**
106.
* 晃动动画
107.
*
108.
* @param counts
109.
* 1秒钟晃动多少下
110.
* @return
111.
*/
112.
public
static
Animation shakeAnimation(
int
counts) {
113.
Animation translateAnimation =
new
TranslateAnimation(
0
,
10
,
0
,
0
);
114.
//设置一个循环加速器,使用传入的次数就会出现摆动的效果。
115.
translateAnimation.setInterpolator(
new
CycleInterpolator(counts));
116.
translateAnimation.setDuration(
500
);
117.
return
translateAnimation;
118.
}
119.
120.
}
01.
<com.exmaple.ClearEditText
02.
android:id=
"@+id/etUserName"
03.
android:layout_width=
"fill_parent"
04.
android:layout_height=
"30dip"
05.
android:background=
"@null"
06.
android:drawableLeft=
"@drawable/user_login"
07.
android:drawablePadding=
"7dip"
08.
android:hint=
"@string/str_hit_inputname"
09.
android:singleLine=
"true"
10.
android:textSize=
"17sp"
>
11.
12.
<requestFocus />
13.
</com.exmaple.ClearEditText>