【Android】EditText之DrawableRight显

作者: 吾非言 | 来源:发表于2017-08-29 22:20 被阅读271次

    作者:邹峰立,微博:zrunker,邮箱:zrunker@yahoo.com,微信公众号:书客创作,个人平台:www.ibooker.cc

    本文选自书客创作平台第34篇文章。阅读原文

    书客创作

    往往在开发当中,通常会遇到这样的需求,当用户输入密码之后,输入框的右侧显示睁眼或者闭眼的小图标,点击小图标能够实现密码的显示或者隐藏。这样的功能需求非常常见,不同的开发者可能会使用不能的方法,那么如果使用EditText的DrawableRight该如何实现显示和隐藏输入密码呢?

    应用场景

    DrawableRight实现隐藏和现实密码功能,常见密码输入框的特殊设置。

    主要重难点

    1、自定义EditText,构造方法中初始化DrawableRight,通过密码的显示和隐藏状态修改DrawableRight的样式。
    2、DrawableRight点击事件的判断和处理。

    代码实现

    在代码实现之前,首先要了解以下几个方法的含义:

    drawable.setBounds(int, int, int, int);
    

    该方法是Drawable类中的一个方法,表示设置图片边界,左上右下。

    setCompoundDrawables(leftDrawable, topDrawable, rightDrawable, bottomDrawable);
    

    该方法是设置EditText的Drawable,四个参数分别表示左上右下。

    getCompoundDrawables()[i]
    

    该方法是获取EditText的Drawable,获取的是一个数组,该数组有四个值,从0到3分别表示EditText左上右下的Drawable,没有的话则为null。
    了解这几个方法之后,接下来分两步实现DrawableRight清空输入值功能。

    1、自定义EditText

    在cc.ibooker.ibooker目录下创建PasswdEditText,让其继承EditText,并实现构造方法。

    public class PasswdEditText extends android.support.v7.widget.AppCompatEditText {
        /**
         * 右侧Drawable引入
         */
        private Drawable mDrawableRight;
        /**
         * 判断当前密码打开状态,默认关闭状态
         */
        private boolean isOpen = false;
    
        // 构造方法 1->2->3
        public PasswdEditText(Context context) {
            this(context, null);
        }
    
        public PasswdEditText(Context context, AttributeSet attrs) {
            this(context, attrs, android.R.attr.editTextStyle);
        }
    
        public PasswdEditText(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        // 初始化方法
        private void init() {
            // Drawable顺序左上右下,0123
            // 获取DrawRight内容
            mDrawableRight = getCompoundDrawables()[2];
            if (mDrawableRight == null) {
                // 未设置默认DrawableRight
                setmDrawableRight(isOpen);
            }
        }
    
        // 初始化DrawableRight
        public void setmDrawableRight(boolean isOpen) {
            int drawableId;
            // 通过状态设置DrawableRight的样式
            if (!isOpen)
                drawableId = R.mipmap.icon_open_eye;
            else
                drawableId = R.mipmap.icon_close_eye;
            // 初始化DrawableRight
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                mDrawableRight = getResources().getDrawable(drawableId, null);
            } else {
                mDrawableRight = getResources().getDrawable(drawableId);
            }
            // 设置Drawable大小和位置
            mDrawableRight.setBounds(0, 0, mDrawableRight.getIntrinsicWidth(), mDrawableRight.getIntrinsicHeight());
            // 将其添加到控件上
            setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], mDrawableRight, getCompoundDrawables()[3]);
        }
    
        // 触摸事件
        // 判断Drawable是否被点击,如果被点击执行点击事件
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_UP:
                    // 获取控件的DrawableRight
                    Drawable drawable = getCompoundDrawables()[2];
                    // 当按下的位置 在EditText的宽度 - 图标到控件右边的间距 - 图标的宽度 与 EditText的宽度 - 图标到控件右边的间距之间,算点击了图标,竖直方向不用考虑
                    // getTotalPaddingRight获取右侧图标以及右侧Padding和
                    // getPaddingRight获取右侧Padding值
                    boolean isTouchRight = event.getX() > (getWidth() - getTotalPaddingRight()) && (event.getX() < ((getWidth() - getPaddingRight())));
                    if (drawable != null && isTouchRight) {
                        // 记录状态
                        isOpen = !isOpen;
                        // 刷新DrawableRight
                        setmDrawableRight(isOpen);
                        // 执行点击事件-隐藏或显示
                        if (isOpen)
                            setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                        else
                            setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                        // 设置光标位置
                        setSelection(getText().length());
                    }
                    break;
            }
            return super.onTouchEvent(event);
        }
    }
    

    2、在布局文件中引入自定义EditText

    直接将自定义的PasswdEditText,引入布局XML文件即可。

    <cc.ibooker.ibooker.PasswdEditText
        android:id="@+id/ed_passwd"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:drawableEnd="@mipmap/icon_eye_open"
        android:drawableRight="@mipmap/icon_eye_open"
        android:inputType="textPassword"
        android:padding="10dp"/>
    

    3、程序结构图

    程序结构图

    Github地址
    阅读原文


    微信公众号:书客创作

    相关文章

      网友评论

        本文标题:【Android】EditText之DrawableRight显

        本文链接:https://www.haomeiwen.com/subject/ospadxtx.html