原文地址:让你的 EditText 所有清除

參考原文:Giving your Edit Texts the All Clear

项目地址(欢迎 Star):ClearEditText

在输入文本的时候,通常当前输入的地方的末尾会有一个 ‘x’ 来结束。它的作用是,假设我们想要清空这一整行输入的时候,点一下 ‘x’ 就能够了。它的存在。还是非常有必要的。

然后。Android UI 组件并没有提供这种功能,假设 Android 用户在输入了一段非常长的文本的时候,发现他全然输错了。这时候想要删除整行内容的话,他必须一直按删除键,或者长按选中整段文字,然后删除。所以说。事实上,这样一个简单 ‘x’ 的存在是非常又必要的。

对于这个 ‘x’ 我们有什么要求呢:

  • ‘x’ 应该仅仅在我们编辑这一项文本的时候而且我们获得了焦点的情况下才显示
  • ‘x’ 应该显示在这项文本内部,即它应该显示在 EditText 里
  • 按下 ‘x’ 应该是清除所有内容
  • ‘x’ 的颜色应该是与编辑文本的主题色是一致的

这些要求意味着我们须要自己定义 EditText。对于第一个要求,我们须要一个 TextWatcher。这种话我们就能够看到内容字段发生的改变。还有我们须要实现 onFocusChangeListener。第二个要求。我们能够实现一个 ‘x’ 作为一个 compound drawable,由于这里没有 onClick 事件去监听 compound drawable,我们须要使用 OnTouch 来监听,这样第三个要求也实现了。对于第四个要求,我觉得 ‘x’ 的颜色应该是和 hint text 的 color 是一样的。

这样才会有“想要就要”的感觉,而不是“我要我要”的感觉。

构建我们的 EditText

创建新的 class。继承自 AppCompatEditText 而非 EditText,以确保我们在所有的设备上都有和 Android5.0 一样的效果。

public class ClearEditText extends AppCompatEditText implements View.OnTouchListener, View.OnFocusChangeListener, TextWatcher {

创建构造函数和进行初始化:

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

在 init 方法中,定义一个清除的图标。由于我们用了 support library。所以能够使用这个图标:abc_ic_clear_mtrl_alpha。可是由于它是白色的,所以我们使用着色(tint)的办法让它在 Android5.0 曾经的设备上也能工作。用 DrawableCompat 类来完毕我们的工作:

private void init(final Context context) {
final Drawable drawable = ContextCompat.getDrawable(context, R.drawable.abc_ic_clear_mtrl_alpha);
final Drawable wrappedDrawable = DrawableCompat.wrap(drawable); //Wrap the drawable so that it can be tinted pre Lollipop
DrawableCompat.setTint(wrappedDrawable, getCurrentHintTextColor());
mClearTextIcon = wrappedDrawable;
mClearTextIcon.setBounds(0, 0, mClearTextIcon.getIntrinsicHeight(), mClearTextIcon.getIntrinsicHeight());
setClearIconVisible(false);
super.setOnTouchListener(this);
super.setOnFocusChangeListener(this);
addTextChangedListener(this);
}

setClearIconVisible 来处理 EditText 的清除图标是否是显示。我们通过焦点的变化和文本的观察(text watchers)来决定显示与否。

private void setClearIconVisible(final boolean visible) {
mClearTextIcon.setVisible(visible, false);
final Drawable[] compoundDrawables = getCompoundDrawables();
setCompoundDrawables(
compoundDrawables[0],
compoundDrawables[1],
visible ? mClearTextIcon : null,
compoundDrawables[3]);
}

这当然意味着使用这种控制你就不应该自己去设置 right 的 compound drawable,由于它总是会被重写为 ‘x’ 或者 null。当文本改变或者焦点变化的时候。

你能够使用 TextInputLayout 来包裹 EditText。

这是非常棒的。

监听其它的控制

细心的你肯定已经注意到了,在 init 方法中我调用了父类的 Touch,和 Focus 的监听事件。

这么做是由于,我想重写标准的设置器,这样我们就能第一时间捕获这些监听。这样就能应用到我们的逻辑里,或者在逻辑里去设置监听。通过这种方式,假设我们用 TextInputLayout 包裹住了 EditText, 然后有 focus 监听。

这种话这些设置在 EditText 也仍然会被 fired。

我们不须要 text watchers,由于你已经有了多个的 multiple text watchers 在编辑文本上。

@Override
public void setOnFocusChangeListener(final OnFocusChangeListener onFocusChangeListener) {
mOnFocusChangeListener = onFocusChangeListener;
} @Override
public void setOnTouchListener(final OnTouchListener onTouchListener) {
mOnTouchListener = onTouchListener;
}

为这个新类定义一些字段:

private Drawable mClearTextIcon;
private OnFocusChangeListener mOnFocusChangeListener;
private OnTouchListener mOnTouchListener;

终于

实现3个监听。首先是 focus:

@Override
public void onFocusChange(final View view, final boolean hasFocus) {
if (hasFocus) {
setClearIconVisible(getText().length() > 0);
} else {
setClearIconVisible(false);
}
if (mOnFocusChangeListener != null) {
mOnFocusChangeListener.onFocusChange(view, hasFocus);
}
}

这样当 focus 改变的时候,假设 editText 是获得焦点的,而且文本内容不为空,我们就显示 清除的 icon,否则。我们就设置为 null(即不显示 icon),在这两种情况下。我们要对其它所有的 focus 改变进行监听,来确保它的逻辑是正常进行的。

onTouch 事件:

@Override
public boolean onTouch(final View view, final MotionEvent motionEvent) {
final int x = (int) motionEvent.getX();
if (mClearTextIcon.isVisible() && x > getWidth() - getPaddingRight() - mClearTextIcon.getIntrinsicWidth()) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
setText("");
}
return true;
}
return mOnTouchListener != null && mOnTouchListener.onTouch(view, motionEvent);
}

我们先检查清除的 icon 是否是显示的。然后当我们点击右側区域,我们就应该始终消耗这个事件,我们不希望其它的 touch 监听获取到。最后,假设用户的手指是从 ‘x’ 所在的区域抬起来的。我们就要去清除文本。

假设 ‘x’ 是不显示的或者 onTouch 事件不是在 right drawable 区域内的,我们就应该处理其它的相应的 touch 监听。

最后是简单的 TextWatcher:

@Override
public final void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
if (isFocused()) {
setClearIconVisible(s.length() > 0);
}
} @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
} @Override
public void afterTextChanged(Editable s) {
}

这样,我们就拥有了带有 ‘x’ 可清除的全功能的的 EditText。你能够在你的布局中替换常规的 EditText 了。

假设你是使用 AutoCompleteTextView 。也是能够改动的。仅仅要该类名为例如以下即可了:

public class ClearableAutoCompleteTextView extends AppCompatAutoCompleteTextView implements View.OnTouchListener, View.OnFocusChangeListener, TextWatcher {

让你的 EditText 所有清除的更多相关文章

  1. Android EidtText 光标的使用和设置

    使光标移动到制定的位置: editText.setSelection(editText.length()); 输入的参数是个整数   在请求出现光标是,也就是在获取焦点时: editText.requ ...

  2. [Android教程]EditText设置/隐藏光标位置、选中文本和获取/清除焦点

      有时候需要让光标显示在EditText的指定位置或者选中某些文本.同样,为了方便用户输入以提升用户体验,可能需要使EditText获得或失去焦点. 1. 设置光标到指定位置 EditText et ...

  3. LayoutInflater作用及使用--自定义EditText,自带清除内容按钮

    作用: 1.对于一个没有被载入或者想要动态载入的界面, 都需要使用inflate来载入. 2.对于一个已经载入的Activity, 就可以使用实现了这个Activiyt的的findViewById方法 ...

  4. Android自定义控件实现带有清除按钮的EditText

    首先声明我也是参考了别人的思路,只是稍微做了下修改,增加显示密码与隐藏密码,没有输入字符串时让EditText进行抖动,废话少说这里附上效果图 效果很赞有木有 那么怎么实现这种效果呢?那就跟着我一起来 ...

  5. EditText设置/隐藏光标位置、选中文本和获取/清除焦点(转)

    转:http://blog.csdn.net/dajian790626/article/details/8464722 有时候需要让光标显示在EditText的指定位置或者选中某些文本.同样,为了方便 ...

  6. Android 带清除功能的输入框控件EditText

    1.效果图      2.源码下载 http://download.csdn.net/detail/yanzi2015/8864603 3.相关博客 http://www.cnblogs.com/to ...

  7. ListView 中含有 EditText 导致焦点丢失的问题

    ListView 中的 item 中有 EditText 时. 如果activity的输入法选项设置为 android:windowSoftInputMode="adjustResize&q ...

  8. Android 带清除功能的输入框控件ClearEditText,仿IOS的输入框

    转载请注明出处http://blog.csdn.net/xiaanming/article/details/11066685 今天给大家带来一个很实用的小控件ClearEditText,就是在Andr ...

  9. 带清空按钮的EditText

    public class ClearEditText extends EditText implements OnFocusChangeListener, TextWatcher { // 删除按钮的 ...

随机推荐

  1. 【搜索】P1019 单词接龙

    题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...

  2. 日常[splay]:水题记——普通平衡树(死亡调试)

    普通平衡树,模板的不能再模板的模板题.我调了两个小时... 早先看yyb大神的blog学习splay,看的风生水起然而没有发现,大神的坑没有填……没有rank操作和k_th操作. 只能自己摸索,问问大 ...

  3. Eclipse的PyDev插件安装及解决安装后找不到的问题

    一.环境 windows 7 64bit eclipse 4.5.2 pydev jdk7u55 二.安装步骤 1. 安装JDK eclipse依赖于Java环境,所以需要安装Java运行环境JRE. ...

  4. JavaScript中通过原型添加方法,解决数据共享问题,节省内存空间

    涉及知识点:(1)原型的引入(2)构造函数.原型对象和实例对象之间的关系(3)__proto__和prototype的理解 直接举例:在自定义构造函数创建对象时,因为创建的对象使用的不是同一个方法,所 ...

  5. Python的串口

    要使用python中的串口,可以下载pywin32-224-cp36-cp36m-win_amd64.whl去安装或者pip install去安装. 调试下来,有一点很不爽,读取read()数据的ti ...

  6. 了解DOM

    DOM是为了方便处理层次型文档(如XML.HTML)的一种技术.DOM还提供了一套API,使开发人员可以用面向对象的方式来处理这些文档.对于XML文档来说,有专门的处理XML文档是XML  DOM,一 ...

  7. CSS小知识点一

    1.   text-indent属性    缩进文本 通过使用 text-indent 属性,所有元素的第一行都可以缩进一个给定的长度,甚至该长度可以是负值.这个属性最常见的用途是将段落的首行缩进,一 ...

  8. NYOJ-183赚钱啦,bellman//spfa水过,,题还是蛮变态的赶脚~~

    赚钱啦 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描述 某国家里有N个城市,分别编号为0~N-1,一个精明的商人准备从0号城市旅行到N-1号城市,在旅行的过程中,从一个城 ...

  9. SPOJ FAVDICE 数学期望

    题目大意: 一个有n面的色子抛掷多少次能使所有面都能被抛到过,求期望值 总面数为n,当已经抛到过 i 个不同面时,我们抛出下一个不同面的概率为 (n-i)/n,那么抛的次数为 n/(n-i) 将所有抛 ...

  10. 【搜索】codeforces C. The Tag Game

    http://codeforces.com/contest/813/problem/C [题意] 给定一棵有n个结点的树,初始时Alice在根结点1,Bob在非根结点x; Alice和Bob轮流走,每 ...