自定义可以点击图标的EditText

作者: waiwaaa | 来源:发表于2018-08-24 09:48 被阅读84次

           在开发APP布局时候经常会看到在EditText的右侧或者左侧出现类似ICON,比如查看密码,点击可以清空输入的字符等,我们通常的做法中在EditText外层再套一层LinearLayout,这无疑增加了布局的复杂度。
           今天我们通过扩展EditText来实现四个drawable都可以点击的功能。

    实现思路

           重写onTouchEvent,当用户点击时,判断点击点是否在图标的位置上,如果在就拦截掉点击事件,调用点击图标的回调

    实现步骤

    • 通过getCompoundDrawables()取得四个方向的drawable
    • 取得点击的坐标
    • 把坐标转换到drawable的坐标体系,难点为需要考虑到有多个的情况,所以左右的图标y通过文本垂直中线来计算,上下图标的x同理
    • 分别判断坐标是否包含在图标区域拦截事件

    完整实现类

    package com.yy.drawableclickedittextdemo;
    
    import android.content.Context;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    
    public class ClickDrawableEditText extends android.support.v7.widget.AppCompatEditText {
        private static String tag= ClickDrawableEditText.class.getSimpleName();
        //点击位置
        private int positionX = 0;
        private int positionY;
        // 回调接口
        private OnDrawableClickListener onDrawableClickListener;
    
        public ClickDrawableEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
        public ClickDrawableEditText(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        public void setOnDrawableClickListener(OnDrawableClickListener onDrawableClickListener) {
            this.onDrawableClickListener = onDrawableClickListener;
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //图标区域
            Rect bounds;
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                positionX = Math.round(event.getX());
                positionY = Math.round(event.getY());
    
                Drawable[] ds=this.getCompoundDrawables();
                Drawable drawableRight = ds[2];
                Drawable drawableLeft = ds[0];
                Drawable drawableTop = ds[1];
                Drawable drawableBottom = ds[3];
    
                //计算点击点在Drawable中的位置
                int xClickPosition,yClickPosition;
                //长宽
                int w=getWidth();
                int h=getHeight();
    
                //文本中心的坐标
                int midX=(w-getTotalPaddingLeft()-getTotalPaddingRight())/2+getTotalPaddingLeft();
                int midY=(h-getTotalPaddingTop()-getTotalPaddingBottom())/2+getTotalPaddingTop();
    
                if (drawableLeft != null) {
                    bounds = drawableLeft.getBounds();
                    // 转换到drawableLeft坐标系统
                    xClickPosition = positionX-getPaddingLeft();
                    yClickPosition = (midY-positionY)+bounds.height()/2;
    
                    if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
                        onDrawableClickListener.onClick(DrawablePosition.LEFT);
                        event.setAction(MotionEvent.ACTION_CANCEL);
                        return false;
                    }
                }
    
                if (drawableRight != null) {
                    bounds = drawableRight.getBounds();
    
                    xClickPosition = positionX - w + bounds.right +getPaddingRight();
                    yClickPosition= (midY-positionY)+bounds.height()/2;
    
                    if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
                        onDrawableClickListener.onClick(DrawablePosition.RIGHT);
                        event.setAction(MotionEvent.ACTION_CANCEL);
                        return false;
                    }
                }
    
                if (drawableTop != null) {
                    bounds = drawableTop.getBounds();
    
                    xClickPosition = (midX - positionX)+bounds.width()/2;
                    yClickPosition= positionY - getPaddingTop();
    
                    if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
                        onDrawableClickListener.onClick(DrawablePosition.TOP);
                        event.setAction(MotionEvent.ACTION_CANCEL);
                        return false;
                    }
                }
    
                if(drawableBottom!=null)
                {
                    bounds = drawableBottom.getBounds();
    
                    xClickPosition = (midX - positionX)+bounds.width()/2;
                    yClickPosition= positionY - h + bounds.height()+ getPaddingBottom();
    
                    if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
                        onDrawableClickListener.onClick(DrawablePosition.BOTTOM);
                        event.setAction(MotionEvent.ACTION_CANCEL);
                        return false;
                    }
                }
            }
            return super.onTouchEvent(event);
        }
    
        /**
         * 设置点击图标的侦听接口
         */
        public interface OnDrawableClickListener{
            public void onClick(int position);
        }
    
        /**
         * 图标的位置方向
         */
        public final static class DrawablePosition{
            public final static int LEFT=0;
            public final static int TOP=1;
            public final static int RIGHT=2;
            public final static int BOTTOM=3;
        }
    }
    
    

    引用

    在xml布局中引用控件

    <com.yy.drawableclickedittext.ClickDrawableEditText
                        android:id="@+id/password"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:hint="@string/prompt_password"
                        android:padding="0dp"
                        android:drawablePadding="10dp"
                        android:imeActionLabel="@string/action_sign_in_short"
                        android:inputType="textPassword"
                        android:maxLines="1"
                        android:singleLine="true"
                        android:drawableRight="@mipmap/city_icon_care"
                        android:drawableLeft="@mipmap/ic_launcher_round"
                        android:drawableTop="@mipmap/city_icon_care"
                        android:drawableBottom="@mipmap/ic_launcher_round"
                        />
    

    在界面中增加点击侦听

    mPasswordView.setOnDrawableClickListener(new ClickDrawableEditText.OnDrawableClickListener() {
                @Override
                public void onClick(int position) {
                    String str="";
                    switch (position){
                        case ClickDrawableEditText.DrawablePosition.LEFT:
                            str="click left";
                            break;
                        case ClickDrawableEditText.DrawablePosition.TOP:
                            str="click top";
                            break;
                        case ClickDrawableEditText.DrawablePosition.RIGHT:
                            str="click right";
                            break;
                        case ClickDrawableEditText.DrawablePosition.BOTTOM:
                            str="click bottom";
                            break;
    
                    }
                    Toast.makeText(LoginActivity.this,str,Toast.LENGTH_SHORT).show();
                }
            });
    

    demo下载

    如果需要完整demo,请点击GitHub下载链接

    相关文章

      网友评论

        本文标题:自定义可以点击图标的EditText

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