Android控件--ClearEditText带清除功能的输入框

来源:互联网 发布:破解软件盒子下载 编辑:程序博客网 时间:2024/05/16 00:55

说明


有的时候我们写布局的时候难免会遇到给控件设置drawableRight或者是drawableleft这样的属性为控件添加个图标之类的情况。
比方说我们做登录界面的时候,账号的框框里可能要显示一个人头的小图标,密码框可能要显示一个小锁的图标。
当然这些只是显示的问题,不会有太大难度。现在其实有很多的图标显示在右边的,而且这些小图标都是需要响应一些点击事件的,比如一按清除图标,清除整行文字,这个我们该怎么做呢,显然Onclick肯定是不可以的。那有人也许会想,可能会有相应的点击事件,其实我想说这个真的没有。
资源链接http://blog.csdn.net/xiaanming/article/details/11066685

效果图如下:
这里写图片描述

工程结构图:
这里写图片描述

1. ClearEdit的JAVA类文件

package com.example.clearedittextone;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.animation.Animation;import android.view.animation.CycleInterpolator;import android.view.animation.TranslateAnimation;import android.widget.EditText;/** * Created by Administrator on 2016/7/7 0007. */public class ClearEditText extends EditText implements View.OnFocusChangeListener,TextWatcher {    //定义右侧的删除按钮    private Drawable mClearDrawable;    //判断控件是否有焦点    private boolean hasFoucs;    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){//        this(context,attrs,defStyle);//        init();//    }    public ClearEditText(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init();    }    public void init(){        // 获取EditText的DrawableRight,假如没有设置我们就使用默认的图片,获取图片的顺序是左上右下(0,1,2,3,)        mClearDrawable = getCompoundDrawables()[2];        if (mClearDrawable == null) {            mClearDrawable = getResources().getDrawable(                    R.drawable.edit_delete);        }        mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(),                mClearDrawable.getIntrinsicHeight());        // 默认设置隐藏图标        setClearIconVisible(false);        // 设置焦点改变的监听        setOnFocusChangeListener(this);        // 设置输入框里面内容发生改变的监听        addTextChangedListener(this);    }    /* @说明:isInnerWidth, isInnerHeight为ture,触摸点在删除图标之内,则视为点击了删除图标     * event.getX() 获取相对应自身左上角的X坐标     * event.getY() 获取相对应自身左上角的Y坐标     * getWidth() 获取控件的宽度     * getHeight() 获取控件的高度     * getTotalPaddingRight() 获取删除图标左边缘到控件右边缘的距离     * getPaddingRight() 获取删除图标右边缘到控件右边缘的距离     * isInnerWidth:     *  getWidth() - getTotalPaddingRight() 计算删除图标左边缘到控件左边缘的距离     *  getWidth() - getPaddingRight() 计算删除图标右边缘到控件左边缘的距离     * isInnerHeight:     *  distance 删除图标顶部边缘到控件顶部边缘的距离     *  distance + height 删除图标底部边缘到控件顶部边缘的距离     */    @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()的时候,我们把我们保存的密码显示在用户名输入框和密码输入框里面,输入框里面内容发生改变,导致用户名输入框和密码输入框里面的清除小图标都显示了,这显然不是我们想要的效果,所以加了一个是否有焦点的判断

    1. setShakeAnimation(),这个方法是输入框左右抖动的方法,之前我在某个应用看到过类似的功能,当用户名错误,输入框就在哪里抖动,感觉挺好玩的,其实主要是用到一个移动动画,然后设置动画的变化率为正弦曲

2. 引用ClearEditText的XML文件

<com.example.clearedittextone.ClearEditText        android:id="@+id/user_name"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:drawableLeft="@drawable/user_name"        android:drawablePadding="7dp"        android:layout_marginTop="10dp"        android:hint="@string/name_tip"        android:singleLine="true"        android:textSize="17sp" >        <requestFocus />    </com.example.clearedittextone.ClearEditText>    <com.example.clearedittextone.ClearEditText        android:id="@+id/password"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:drawableLeft="@drawable/lock1"        android:inputType="textPassword"        android:drawablePadding="7dp"        android:layout_marginTop="60dp"        android:hint="@string/name_tip"        android:singleLine="true"        android:textSize="17sp" >        <requestFocus />    </com.example.clearedittextone.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:textSize="18sp"        android:textColor="@android:color/white"        android:layout_below="@+id/password"        android:layout_marginTop="25dp"        android:text="登录" />

Strings文件

<resources>    <string name="app_name">ClearEditTextOne</string>    <string name="name_tip">请输入用户名</string></resources>

3. MainActivity的JAVA类文件

package com.example.clearedittextone;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.text.TextUtils;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    private Toast mToast;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        final ClearEditText user_name  = (ClearEditText) findViewById(R.id.user_name);        final ClearEditText password  = (ClearEditText) findViewById(R.id.password);        Button button = (Button) findViewById(R.id.login);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if(TextUtils.isEmpty(user_name.getText())){                    user_name.setShakeAnimation();                    showToast("用户名不能为空");                    return;                }                if(TextUtils.isEmpty(password.getText())){                    password.setShakeAnimation();                    showToast("密码不能为空");                    return;                }            }        });    }    private void showToast(String msg){        if(mToast == null){            mToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);        }else{            mToast.setText(msg);        }        mToast.show();    }}

requestFocus这个标签是干什么的?
标签用于指定屏幕内的焦点View。

例如我们点击tab键或enter键焦点自动进入下一个输入框;
就是说你得第一个会获得焦点,意思就是如果你给某个edittext设置了标记,并且这个edittext前面没有设置标记的控件 那么这个edittext就会获得焦点,也就是输入的那个光标。

0 0
原创粉丝点击