您的位置:首页 > 移动开发 > 微信开发

Android仿微信带清除功能的输入框ClearEditText的实现

2016-03-23 19:15 666 查看
转载请注明出处:/article/7707986.html

今天跟大家分享一个控件ClearEditText-带清除功能的输入框。其实这个控件在IOS中很简单,只需要设置属性即可,但是在Android中就变得不是那么容易了。先说说我自己的设计思路:首先,输入框右边得加一个删除图标;其次,删除图标的显示和隐藏(当我们的输入框有内容输入了并且有焦点,我们显示删除图标;当输入框没有焦点,我们也隐藏图标;当输入框中没有内容了,我们隐藏删除图标);再次,点击删除图标,我们清空输入框中的内容,并隐藏删除图标。

那么下面我们来看看具体要怎么去实现呢?第一个问题就是我们怎么去给输入框右边添加删除图标,这个方法有多种,比如可以采用线性布局左边放一个EditText,右边放一个ImageView;设置EditText的属性值android:drawableRight。我采用的是后面的方法,就是直接给EditText设置属性值,这样我们的图标问题就解决了。下面我们来看一下效果图(为了好看点,drawableLeft我也设置了一个图标):



好了,接下来遇到问题了,就是android本身没有方法去对右边删除图标进行点击监听,那我们有没有办法间接的去实现它呢?当然是有的。我们其实可以通过EditText的Touch事件,来判断用户是否点击了删除图标的区域,如果是则表明点击了删除图标,否则就没有点击删除图标。下面我们看代码是怎么去实现这一过程的:

package com.wuping.clearedittext;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.EditText;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;

public class ClearEditText extends EditText implements OnFocusChangeListener, TextWatcher {

/* 右边删除图标的引用 */
private Drawable mClearDrawable;

/* 输入框是否有焦点 */
private boolean hasFocus;

public ClearEditText(Context context) {
this(context, null);
}

public ClearEditText(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.editTextStyle);
}

public ClearEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

private void init() {
mClearDrawable = getResources().getDrawable(R.drawable.clear);
mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
// 删除图标默认隐藏
setClearIconVisible(false);
// 设置输入框焦点改变监听
setOnFocusChangeListener(this);
// 设置输入框中内容发生改变监听
addTextChangedListener(this);
}

/**
* 当visible为true时,删除图标显示,当visible为false时,图标隐藏
* @param visible
*/
private void setClearIconVisible(boolean visible) {
Drawable rightDrawable = visible ? mClearDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], rightDrawable,
getCompoundDrawables()[3]);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
if (getCompoundDrawables()[2] != null) {
boolean isClear = (event.getX() > (getWidth() - getTotalPaddingRight()))
&& (event.getX() < (getWidth() - getPaddingRight()));
if (isClear) {
setText("");
}
}
break;

default:
break;
}
return super.onTouchEvent(event);
}

/**
* 当控件的焦点发生改变时会调用该方法。
* 当控件有焦点并且内容长度不为0则显示clear图标,否则隐藏。
*/
@Override
public void onFocusChange(View v, boolean hasFocus) {
this.hasFocus = hasFocus;
if(hasFocus){
setClearIconVisible(getText().length() > 0);
}else{
setClearIconVisible(false);
}
}

/**
* 当控件的有内容改变时调用此方法。
* 有焦点并且内容长度不为0则显示clear图标,否则隐藏。
*/
@Override
public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
if(hasFocus){
setClearIconVisible(text.length() > 0);
}
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub

}

@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub

}

}
看onTouchEvent()方法:当我们触摸抬起(就是ACTION_UP的时候)的范围
大于输入框左侧到clear图标左侧的距离,小与输入框左侧到clear图标右侧的距离,我们则认为是点击clear图标.

*getWidth():得到控件的宽度

* event.getX():抬起时的坐标(该坐标是相对于控件本身而言的)

* getTotalPaddingRight():clear图标左边缘至控件右边缘的距离

* getPaddingRight():clear图标右边缘至控件右边缘的距离

于是: getWidth() - getTotalPaddingRight()表示:
控件左边到clean的图标左边缘的区域 ;getWidth() - getPaddingRight()表示: 控件左边到clear图标右边缘的区域 。所以这两者之间的区域刚好是clear图标的区域。

setClearIconVisible()方法中,是利用setCompoundDrawables()方法来为ClearEditText绘制左右图标的,从而来控制clear图标的显示和隐藏。

setOnFocusChangeListener(this)是给控件设置了焦点改变监听。如果控件失去焦点,则隐藏clear图标,如果有焦点且内容长度不为0则显示图标。

addTextChangedListener(this)是给控件设置了内容改变监听。当控件有文字输入或删除就会调用相应的回调方法。

好了,下面我们来使用这个带清除功能的控件。

先写一个布局,如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.wuping.clearedittext.ClearEditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:singleLine="true"
android:inputType="text"
android:hint="输入密码"
android:drawableLeft="@drawable/password"
android:drawableRight="@drawable/clear" />

<com.wuping.clearedittext.ClearEditText
android:layout_below="@id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:singleLine="true"
android:inputType="text"
android:hint="确认密码"
android:drawableLeft="@drawable/password"
android:drawableRight="@drawable/clear" />

</RelativeLayout>
直接运行程序,就可以了。效果我就不演示了,大家可以自己写个Demo测试,有什么问题请评论提出,谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: