
当点击密码框右侧的小×图标时输入的内容就都清空了,真的很方便,我之前在项目中也自定义过这种效果的输入框并且在项目中一直使用它,在此期间并没有发现什么Bug,之前的自定义结构如下:

实现方式是使用一个RelativeLayout,它包含了三个控件,两边是ImageView控件,中间是EditText控件,当点击右侧清除按钮后就可以清除输入框的内容了,但是最近在做产品优化的时候感觉之前写的这个自定义控件在代码量上来说有点浪费,明明Android的EditText有drawableLeft和drawableRight属性,为什么不去直接使用呢?于是用笔在草稿纸上画了画,花点时间又重新写了一个具有同样效果的输入框,并且在代码量上来说简化了不少。
好了,还是老规矩,先来看看项目结构吧:
工程中ClearEditText就是我又从新定义的带清除功能的输入框,主要是继承了EditText为了利用它的drawableLeft和drawableRight属性,那么赶紧看看它的实现吧
public class ClearEditText extends EditText implements TextWatcher, OnFocusChangeListener {/*** 左右两侧图片资源*/ private Drawable left, right; /*** 是否获取焦点,默认没有焦点*/ private boolean hasFocus = false; /*** 手指抬起时的X坐标*/ private int xUp = 0;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 defStyle) { super(context, attrs, defStyle); initWedgits(); }/*** 初始化各组件* @param attrs*属性集*/ private void initWedgits() { try { // 获取drawableLeft图片,如果在布局文件中没有定义drawableLeft属性,则此值为空 left = getCompoundDrawables()[0]; // 获取drawableRight图片,如果在布局文件中没有定义drawableRight属性,则此值为空 right = getCompoundDrawables()[2]; initDatas(); } catch (Exception e) { e.printStackTrace(); } }/*** 初始化数据*/ private void initDatas() { try { // 第一次显示,隐藏删除图标 setCompoundDrawablesWithIntrinsicBounds(left, null, null, null); addListeners(); } catch (Exception e) { e.printStackTrace(); } }/*** 添加事件监听*/ private void addListeners() { try { setOnFocusChangeListener(this); addTextChangedListener(this); } catch (Exception e) { e.printStackTrace(); } }@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { }@Override public void onTextChanged(CharSequence s, int start, int before, int after) { if (hasFocus) { if (TextUtils.isEmpty(s)) { // 如果为空,则不显示删除图标 setCompoundDrawablesWithIntrinsicBounds(left, null, null, null); } else { // 如果非空,则要显示删除图标 if (null == right) { right = getCompoundDrawables()[2]; } setCompoundDrawablesWithIntrinsicBounds(left, null, right, null); } } }@Override public boolean onTouchEvent(MotionEvent event) { try { switch (event.getAction()) { case MotionEvent.ACTION_UP: // 获取点击时手指抬起的X坐标 xUp = (int) event.getX(); // 当点击的坐标到当前输入框右侧的距离小于等于getCompoundPaddingRight()的距离时,则认为是点击了删除图标 // getCompoundPaddingRight()的说明:Returns the right padding of the view, plus space for the right Drawable if any. if ((getWidth() - xUp) <= getCompoundPaddingRight()) { if (!TextUtils.isEmpty(getText().toString())) { setText(""); } } break; default: break; } } catch (Exception e) { e.printStackTrace(); } return super.onTouchEvent(event); }@Override public void afterTextChanged(Editable s) { }@Override public void onFocusChange(View v, boolean hasFocus) { try { this.hasFocus = hasFocus; } catch (Exception e) { e.printStackTrace(); } } } 解释一下ClearEditText的执行顺序,它首先继承了EditText也就是说具有了EditText的所有功能,然后又实现了TextWatcher和OnFocusChangeListener接口,其中接口OnFocusChangeListener是用来监听当前输入框是否获取到焦点的,我们把当前输入框获取到的焦点的状态值赋给hasFocus成员变量,如果获取到了焦点则hasFocus的值为true,当在输入框中输入内容的时候会触发TextWatcher监听器,就会顺序执行beforeTextChanged,onTextChanged和afterTextChanged方法,而我们仅仅需要在onTextChanged方法中对输入框的值进行判断就行了,如果输入框框的值非空就显示清空按钮小图标否则不显示,设置图标隐藏和显示的方法就是直接调用setCompoundDrawablesWithIntrinsicBounds方法就行了,这个方法的具体使用就不详解了,大体就是说按照我们给定的图片尺寸把图片画到输入框的四个方向上,如果传入值为null就表示不绘制。<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dip" android:text="@string/hello" android:gravity="center" android:textSize="20sp" android:textColor="#000000" /><com.llew.e.clear.view.wedgit.ClearEditText android:id="@+id/clearEditText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dip" android:paddingRight="8dip" android:paddingTop="5dip" android:paddingBottom="5dip" android:hint="请输入QQ号码" android:background="@drawable/pay_widget_input" android:drawableLeft="@drawable/super_qq" android:drawableRight="@drawable/clear_normal_list" /></LinearLayout>就是写完整我们自定义的包名就行了,属性用的全是父类中的,再次感谢Java给我们提供的继承特性,呵呵,
public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } } 简单吧?创建工程的时候自动生成的,压根不用进行任何操作,呵呵
输入后:

点击清除图标后:

呵呵,这种效果和之前自定义的一样,并且在代码量上来说却是比之前的减少了不少,高兴一下
好了,今天的自定义ClearEditText就讲到这里,感谢收看。
源码下载:Android UI实现带清除功能的输入框
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。