Android输入框控件ClearEditText实现清除功能

本文给大家带来一个很实用的小控件ClearEditText,就是在Android系统的输入框右边加入一个小图标,点击小图标可以清除输入框里面的内容,IOS上面直接设置某个属性就可以实现这一功能,但是Android原生EditText不具备此功能,所以要想实现这一功能我们需要重写EditText,接下来就带大家来实现这一小小的功能
我们知道,我们可以为我们的输入框在上下左右设置图片,所以我们可以利用属性android:drawableRight设置我们的删除小图标,如图

我这里设置了左边和右边的图片,如果我们能为右边的图片设置监听,点击右边的图片清除输入框的内容并隐藏删除图标,这样子这个小功能就迎刃而解了,可是Android并没有给允许我们给右边小图标加监听的功能,这时候你是不是发现这条路走不通呢,其实不是,我们可能模拟点击事件,用输入框的的onTouchEvent()方法来模拟,
当我们触摸抬起(就是ACTION_UP的时候)的范围  大于输入框左侧到清除图标左侧的距离,小与输入框左侧到清除图片右侧的距离,我们则认为是点击清除图片,当然我这里没有考虑竖直方向,只要给清除小图标就上了监听,其他的就都好处理了,我先把代码贴上来,在讲解下

package com.example.clearedittext; 

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

public class ClearEditText extends EditText implements
    OnFocusChangeListener, TextWatcher {
  /**
   * 删除按钮的引用
   */
  private Drawable mClearDrawable;
  /**
   * 控件是否有焦点
   */
  private boolean hasFoucs; 

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

  public ClearEditText(Context context, AttributeSet attrs) {
    //这里构造方法也很重要,不加这个很多属性不能再XML里面定义
    this(context, attrs, android.R.attr.editTextStyle);
  }  

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

  private void init() {
    //获取EditText的DrawableRight,假如没有设置我们就使用默认的图片
    mClearDrawable = getCompoundDrawables()[2];
    if (mClearDrawable == null) {
//     throw new NullPointerException("You can add drawableRight attribute in XML");
      mClearDrawable = getResources().getDrawable(R.drawable.delete_selector);
    }  

    mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
    //默认设置隐藏图标
    setClearIconVisible(false);
    //设置焦点改变的监听
    setOnFocusChangeListener(this);
    //设置输入框里面内容发生改变的监听
    addTextChangedListener(this);
  }  

  /**
   * 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件
   * 当我们按下的位置 在 EditText的宽度 - 图标到控件右边的间距 - 图标的宽度 和
   * EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向就没有考虑
   */
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_UP) {
      if (getCompoundDrawables()[2] != null) { 

        boolean touchable = event.getX() > (getWidth() - getTotalPaddingRight())
            && (event.getX() < ((getWidth() - getPaddingRight()))); 

        if (touchable) {
          this.setText("");
        }
      }
    } 

    return super.onTouchEvent(event);
  } 

  /**
   * 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏
   */
  @Override
  public void onFocusChange(View v, boolean hasFocus) {
    this.hasFoucs = hasFocus;
    if (hasFocus) {
      setClearIconVisible(getText().length() > 0);
    } else {
      setClearIconVisible(false);
    }
  }  

  /**
   * 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去
   * @param visible
   */
  protected void setClearIconVisible(boolean visible) {
    Drawable right = visible ? mClearDrawable : null;
    setCompoundDrawables(getCompoundDrawables()[0],
        getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
  }  

  /**
   * 当输入框里面内容发生变化的时候回调的方法
   */
  @Override
  public void onTextChanged(CharSequence s, int start, int count,
      int after) {
        if(hasFoucs){
          setClearIconVisible(s.length() > 0);
        }
  }  

  @Override
  public void beforeTextChanged(CharSequence s, int start, int count,
      int after) {  

  }  

  @Override
  public void afterTextChanged(Editable s) {  

  }  

  /**
   * 设置晃动动画
   */
  public void setShakeAnimation(){
    this.setAnimation(shakeAnimation(5));
  } 

  /**
   * 晃动动画
   * @param counts 1秒钟晃动多少下
   * @return
   */
  public static Animation shakeAnimation(int counts){
    Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
    translateAnimation.setInterpolator(new CycleInterpolator(counts));
    translateAnimation.setDuration(1000);
    return translateAnimation;
  } 

}

setClearIconVisible()方法,设置隐藏和显示清除图标的方法,我们这里不是调用setVisibility()方法,setVisibility()这个方法是针对View的,我们可以调用setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom)来设置上下左右的图标
setOnFocusChangeListener(this) 为输入框设置焦点改变监听,如果输入框有焦点,我们判断输入框的值是否为空,为空就隐藏清除图标,否则就显示
addTextChangedListener(this) 为输入框设置内容改变监听,其实很简单呢,当输入框里面的内容发生改变的时候,我们需要处理显示和隐藏清除小图标,里面的内容长度不为0我们就显示,否是就隐藏,但这个需要输入框有焦点我们才改变显示或者隐藏,为什么要需要焦点,比如我们一个登陆界面,我们保存了用户名和密码,在登陆界面onCreate()的时候,我们把我们保存的密码显示在用户名输入框和密码输入框里面,输入框里面内容发生改变,导致用户名输入框和密码输入框里面的清除小图标都显示了,这显然不是我们想要的效果,所以加了一个是否有焦点的判断
setShakeAnimation(),这个方法是输入框左右抖动的方法,之前我在某个应用看到过类似的功能,当用户名错误,输入框就在哪里抖动,感觉挺好玩的,其实主要是用到一个移动动画,然后设置动画的变化率为正弦曲线

接下来我们来使用它,Activity的布局,两个我们自定义的输入框,一个按钮

<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"
  android:background="#95CAE4"> 

  <com.example.clearedittext.ClearEditText
    android:id="@+id/username"
    android:layout_marginTop="60dp"
    android:layout_width="fill_parent"
    android:background="@drawable/login_edittext_bg"
    android:drawableLeft="@drawable/icon_user"
    android:layout_marginLeft="10dip"
    android:layout_marginRight="10dip"
    android:singleLine="true"
    android:drawableRight="@drawable/delete_selector"
    android:hint="输入用户名"
    android:layout_height="wrap_content" > 

  </com.example.clearedittext.ClearEditText> 

  <com.example.clearedittext.ClearEditText
    android:id="@+id/password"
    android:layout_marginLeft="10dip"
    android:layout_marginRight="10dip"
    android:layout_marginTop="10dip"
    android:drawableLeft="@drawable/account_icon"
    android:hint="输入密码"
    android:singleLine="true"
    android:password="true"
    android:drawableRight="@drawable/delete_selector"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/username"
    android:background="@drawable/login_edittext_bg" >
  </com.example.clearedittext.ClearEditText> 

  <Button
    android:id="@+id/login"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dip"
    android:layout_marginRight="10dip"
    android:background="@drawable/login_button_bg"
    android:textSize="18sp"
    android:textColor="@android:color/white"
    android:layout_below="@+id/password"
    android:layout_marginTop="25dp"
    android:text="登录" /> 

</RelativeLayout>

然后就是界面代码的编写,主要是测试输入框左右晃动而已,比较简单

package com.example.clearedittext; 

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast; 

public class MainActivity extends Activity {
  private Toast mToast; 

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main); 

    final ClearEditText username = (ClearEditText) findViewById(R.id.username);
    final ClearEditText password = (ClearEditText) findViewById(R.id.password); 

    ((Button) findViewById(R.id.login)).setOnClickListener(new OnClickListener() { 

      @Override
      public void onClick(View v) {
        if(TextUtils.isEmpty(username.getText())){
          //设置晃动
          username.setShakeAnimation();
          //设置提示
          showToast("用户名不能为空");
          return;
        } 

        if(TextUtils.isEmpty(password.getText())){
          password.setShakeAnimation();
          showToast("密码不能为空");
          return;
        }
      }
    });
  } 

  /**
   * 显示Toast消息
   * @param msg
   */
  private void showToast(String msg){
    if(mToast == null){
      mToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
    }else{
      mToast.setText(msg);
    }
    mToast.show();
  } 

} 

运行项目,如图,悲剧,没有动画效果,算了就这样子吧,你是不是也想把它加到你的项目当中去呢,赶紧吧!

以上就是本文的全部内容,希望对大家学习Android软件编程有所帮助。

(0)

相关推荐

  • Android文本输入框(EditText)输入密码时显示与隐藏

    代码很简单,这里就不多废话了. 复制代码 代码如下: package cc.c; import android.app.Activity; import android.os.Bundle; import android.text.Selection; import android.text.Spannable; import android.text.method.HideReturnsTransformationMethod; import android.text.method.Passw

  • Android仿支付宝、京东的密码键盘和输入框

    首先看下效果图 一:布局代码 键盘由0~9的数字,删除键和完成键组成,也可以根据需求通过GridView适配器的getItemViewType方法来定义.点击键的时候背景有变色的效果. 密码输入框由六个EditText组成,每个输入框最对能输入一个数字,监听最后一个输入框来完成密码输入结束的监听. 二:键盘 键盘中的主要逻辑处理,键盘样式,item的点击事件 @Override public int getViewTypeCount() { return 2; } @Override publi

  • Android UI设计系列之自定义EditText实现带清除功能的输入框(3)

    最近公司的产品在陆续做升级,上级领导给的任务是优化代码结构以及项目架构,力争把项目写的精巧简练,于是我们满工程找冗余... 我们都知道每一个项目基本上都是有登陆页的,在登陆页中肯定是少不了输入框了,当我们在输入框中输入数据后如果输入的内容不正确或者是错误的或者是想重新输入,如果嗯键盘上的删除键就得一个一个的去删除,这时候我们或许就想要是能有一个标记当点击了这个标记能把我们刚刚输入的内容清空就好了.这样可以极大的提升用户体验,就拿QQ的登陆来说吧,效果如下: 当点击密码框右侧的小×图标时输入的内容

  • Android实现IP地址输入框的方法示例代码

    前言 本文主要给大家介绍了关于Android实现IP地址格式输入框的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 实现效果图: 解决方案: 1.添加4个EditText和三个TextView 2.设置TextView内容为点,且靠下方.设置EditText背景和边框为透明 3.为每个EditText添加监听事件 示例代码 Layout: <LinearLayout android:layout_width="match_parent" android

  • Android实现动态显示或隐藏密码输入框的内容

    本文实例展示了Android实现动态显示或隐藏密码输入框内容的方法,分享给大家供大家参考之用.具体方法如下: 该功能可通过设置EditText的setTransformationMethod()方法来实现隐藏密码或者显示密码. 示例代码如下: private Button mBtnPassword; private EditText mEtPassword; private boolean mbDisplayFlg = false; /** Called when the activity is

  • android仿微信支付宝的支付密码输入框示例

    大家好,我是狸小华,萌汉子一枚.今天给大家带来的是仿微信/支付宝的密码输入框.这个效果也出来有一段时间了,所以搜索一下还是有不少的网友实现,但是,但是!经过一番查看后,我发现他们的实现分为两大类. 一,直接继承EditText,然后在ondraw里面做文章:二,EditText外面包一个viewGroup.我不喜欢这两种实现方式,觉着有些臃肿了,所以我详细介绍下我的实现方式:直接继承View,获取用户的输入,然后draw出来. 我们实现的是上面的密码输入框,这个键盘...系统自带的哦,调用用户输

  • Android软键盘挡住输入框的终极解决方案

    前言 开发做得久了,总免不了会遇到各种坑. 而在Android开发的路上,『软键盘挡住了输入框』这个坑,可谓是一个旷日持久的巨坑--来来来,我们慢慢看. 入门篇 最基本的情况,如图所示:在页面底部有一个EditText,如果不做任何处理,那么在软键盘弹出的时候,就有可能会挡住EditText. 对于这种情况的处理其实很简单,只需要在AndroidManifest文件中对activity设置:android:windowSoftInputMode的值adjustPan或者adjustResize即

  • android输入框与文本框加滚动条scrollview示例

    我们都知道EditText与TextView是Android的文本输入框和文本显示框,但是基于手机屏幕的大小因素,如果在需要输入较多文字或者显示较多内容的时候,手机屏幕是远远不够的,因此让文本框具有滚动条的功能是手机上必备的,要加上滚动条,其实很简单,只需要在文本输入框或者文本显示框上面加上滚动条控件即可,该控件名字为ScrollView,以下我们对比下(以TextView举例). 复制代码 代码如下: //A.未加滚动效果 <TextView android:layout_width="

  • Android输入法弹出时覆盖输入框问题的解决方法

    当一个activity中含有输入框时,我们点击输入框,会弹出输入法界面,整个界面的变化效果与manifest中对应设置的android:windowSoftInputMode属性有关,一般可以设置的值如下, <activity android:windowSoftInputMode=[ "stateUnspecified", "stateUnchanged", "stateHidden", "stateAlwaysHidden&q

  • Android 仿支付宝密码输入框效果

    模仿支付宝输入效果,实现很简单,就是画个矩形框和圆形,其他的通过组合view来实现所有功能,虽然简单但是封装起来,方便以后使用,也分享一下,希望对别人也有点帮助. 1.如何使用,可以设置自己的进入退出动画,不设置则没有动画效果,自己觉得封装之后还是非常用好的. private MyInputPwdUtil myInputPwdUtil; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(sa

随机推荐