Android 在EditText中处理可绘制图形上的单击事件

Android 在EditText中处理可绘制图形上的单击事件,android,android-studio,android-edittext,android-widget,compound-drawables,Android,Android Studio,Android Edittext,Android Widget,Compound Drawables,我使用以下XML在EditText小部件中添加了文本的图像右侧: <EditText android:id="@+id/txtsearch" ... android:layout_gravity="center_vertical" android:background="@layout/shape" android:hint="Enter place,city,state" android:drawableRight="@drawable/cross" />

我使用以下XML在
EditText
小部件中添加了文本的图像右侧:

<EditText
  android:id="@+id/txtsearch"
  ...
  android:layout_gravity="center_vertical"
  android:background="@layout/shape"
  android:hint="Enter place,city,state"
  android:drawableRight="@drawable/cross" />


但是我想在单击嵌入的图像时清除
EditText
。我如何才能做到这一点?

考虑以下几点。这不是最优雅的解决方案,但它很有效,我刚刚测试过

  • 创建自定义的
    EditText
    CustomEditText.java

    import android.content.Context;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.widget.EditText;
    
    public class CustomEditText extends EditText
    {
      private Drawable dRight;
      private Rect rBounds;
    
      public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
      }
      public CustomEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
      }
      public CustomEditText(Context context) {
        super(context);
      }
    
      @Override
      public void setCompoundDrawables(Drawable left, Drawable top,
          Drawable right, Drawable bottom)
      {
        if(right !=null)
        {
          dRight = right;
        }
        super.setCompoundDrawables(left, top, right, bottom);
      }
    
      @Override
      public boolean onTouchEvent(MotionEvent event)
      {
    
        if(event.getAction() == MotionEvent.ACTION_UP && dRight!=null)
        {
          rBounds = dRight.getBounds();
          final int x = (int)event.getX();
          final int y = (int)event.getY();
          //System.out.println("x:/y: "+x+"/"+y);
          //System.out.println("bounds: "+bounds.left+"/"+bounds.right+"/"+bounds.top+"/"+bounds.bottom);
          //check to make sure the touch event was within the bounds of the drawable
          if(x>=(this.getRight()-rBounds.width()) && x<=(this.getRight()-this.getPaddingRight())
              && y>=this.getPaddingTop() && y<=(this.getHeight()-this.getPaddingBottom()))
          {
            //System.out.println("touch");
            this.setText("");
            event.setAction(MotionEvent.ACTION_CANCEL);//use this to prevent the keyboard from coming up
          }
        }
        return super.onTouchEvent(event);
      }
    
      @Override
      protected void finalize() throws Throwable
      {
        dRight = null;
        rBounds = null;
        super.finalize();
      }
    }
    
  • 最后,将以下内容(或类似内容)添加到您的活动中:

    …
    CustomEditText et = (CustomEditText) this.findViewById(R.id.txtsearch);
    …
    
  • 我可能对嵌套可绘制图形的触摸边界的计算有点不满意,但你明白了

    package com.example.android;
    
    import android.content.Context;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.widget.EditText;
    import android.graphics.Rect;
    
    import com.example.android.DrawableClickListener;
    
    public class ClickableButtonEditText extends EditText {
      public static final String LOG_TAG = "ClickableButtonEditText";
    
      private Drawable drawableRight;
      private Drawable drawableLeft;
      private Drawable drawableTop;
      private Drawable drawableBottom;
      private boolean consumeEvent = false;
      private int fuzz = 0;
    
      private DrawableClickListener clickListener;
    
      public ClickableButtonEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
      }
    
      public ClickableButtonEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
      }
    
      public ClickableButtonEditText(Context context) {
        super(context);
      }
    
      public void consumeEvent() {
        this.setConsumeEvent(true);
      }
    
      public void setConsumeEvent(boolean b) {
        this.consumeEvent = b;
      }
    
      public void setFuzz(int z) {
        this.fuzz = z;
      }
    
      public int getFuzz() {
        return fuzz;
      }
    
      @Override
      public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) {
        if (right != null) {
          drawableRight = right;
        }
    
        if (left != null) {
          drawableLeft = left;
        }
        super.setCompoundDrawables(left, top, right, bottom);
      }
    
      @Override
      public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
          int x, y;
          Rect bounds;
          x = (int) event.getX();
          y = (int) event.getY();
          // this works for left since container shares 0,0 origin with bounds
          if (drawableLeft != null) {
            bounds = drawableLeft.getBounds();
            if (bounds.contains(x - fuzz, y - fuzz)) {
              clickListener.onClick(DrawableClickListener.DrawablePosition.LEFT);
              if (consumeEvent) {
                event.setAction(MotionEvent.ACTION_CANCEL);
                return false;
              }
            }
          } else if (drawableRight != null) {
            bounds = drawableRight.getBounds();
            if (x >= (this.getRight() - bounds.width() - fuzz) && x <= (this.getRight() - this.getPaddingRight() + fuzz) 
                  && y >= (this.getPaddingTop() - fuzz) && y <= (this.getHeight() - this.getPaddingBottom()) + fuzz) {
    
              clickListener.onClick(DrawableClickListener.DrawablePosition.RIGHT);
              if (consumeEvent) {
                event.setAction(MotionEvent.ACTION_CANCEL);
                return false;
              }
            }
          } else if (drawableTop != null) {
            // not impl reader exercise :)
          } else if (drawableBottom != null) {
            // not impl reader exercise :)
          }
        }
    
        return super.onTouchEvent(event);
      }
    
      @Override
      protected void finalize() throws Throwable {
        drawableRight = null;
        drawableBottom = null;
        drawableLeft = null;
        drawableTop = null;
        super.finalize();
      }
    
      public void setDrawableClickListener(DrawableClickListener listener) {
        this.clickListener = listener;
      }
    }
    

    我希望这会有所帮助。

    我扩展了RyanM的想法,创建了一个更灵活的版本,支持所有可绘制类型(顶部、底部、左侧、右侧)。虽然下面的代码扩展了TextView,但将其修改为EditText只是将“extends TextView”替换为“extends EditText”的一种情况。从XML实例化小部件与RyanM示例中相同,除了小部件名称



    DrawableClickListener如下所示:

    public interface DrawableClickListener {
    
    public static enum DrawablePosition { TOP, BOTTOM, LEFT, RIGHT };
    public void onClick(DrawablePosition target); }
    

    然后是实际执行情况:

    class example implements DrawableClickListener {
    public void onClick(DrawablePosition target) {
        switch (target) {
            case LEFT:
                doSomethingA();
                break;
    
            case RIGHT:
                doSomethingB();
                break;
    
            case BOTTOM:
                doSomethingC();
                break;
    
            case TOP:
                doSomethingD();
                break;
    
            default:
                break;
        }
    }}
    


    p、 s:如果不设置侦听器,触摸TextView将导致NullPointerException。您可能想在代码中添加更多的偏执。

    上次使用的
    包含(x,y)
    将不会直接作用于
    getBounds()
    的结果(巧合的是,使用“左”绘图时除外)。
    getBounds
    方法只提供了
    Rect
    定义原点为0,0的可绘制项的点-因此,您实际上需要对原始帖子进行数学运算,以确定单击是否在包含EditText的维度上下文中的可绘制区域中,但将其更改为top,right,左等。或者,您可以描述一个
    Rect
    ,它的坐标实际上相对于它在
    EditText
    容器中的位置,并使用
    contains()
    ,尽管最后您也在做同样的计算

    将两者结合起来可以提供一个非常完整的解决方案,我只添加了一个实例属性
    consumersevent
    ,让API用户通过使用其结果设置
    ACTION\u CANCEL
    来决定是否应该传递click事件

    另外,我不明白为什么
    边界
    actionX
    actionY
    值是实例属性,而不仅仅是堆栈上的本地属性

    这是一个基于以上内容的实现的剪贴画。它修复了一个问题,为了正确使用事件,您需要返回false。它为该模型添加了一个“模糊”因子。在我使用的
    EditText
    字段中的语音控制图标的情况下,我发现很难单击,因此模糊增加了被认为是单击可绘制文本的有效边界。对我来说,
    15
    效果很好。我只需要
    drawableRight
    ,所以我没有在其他部分插入数学,以节省一些空间,但是你看到了这个想法

    package com.example.android;
    
    import android.content.Context;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.widget.EditText;
    import android.graphics.Rect;
    
    import com.example.android.DrawableClickListener;
    
    public class ClickableButtonEditText extends EditText {
      public static final String LOG_TAG = "ClickableButtonEditText";
    
      private Drawable drawableRight;
      private Drawable drawableLeft;
      private Drawable drawableTop;
      private Drawable drawableBottom;
      private boolean consumeEvent = false;
      private int fuzz = 0;
    
      private DrawableClickListener clickListener;
    
      public ClickableButtonEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
      }
    
      public ClickableButtonEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
      }
    
      public ClickableButtonEditText(Context context) {
        super(context);
      }
    
      public void consumeEvent() {
        this.setConsumeEvent(true);
      }
    
      public void setConsumeEvent(boolean b) {
        this.consumeEvent = b;
      }
    
      public void setFuzz(int z) {
        this.fuzz = z;
      }
    
      public int getFuzz() {
        return fuzz;
      }
    
      @Override
      public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) {
        if (right != null) {
          drawableRight = right;
        }
    
        if (left != null) {
          drawableLeft = left;
        }
        super.setCompoundDrawables(left, top, right, bottom);
      }
    
      @Override
      public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
          int x, y;
          Rect bounds;
          x = (int) event.getX();
          y = (int) event.getY();
          // this works for left since container shares 0,0 origin with bounds
          if (drawableLeft != null) {
            bounds = drawableLeft.getBounds();
            if (bounds.contains(x - fuzz, y - fuzz)) {
              clickListener.onClick(DrawableClickListener.DrawablePosition.LEFT);
              if (consumeEvent) {
                event.setAction(MotionEvent.ACTION_CANCEL);
                return false;
              }
            }
          } else if (drawableRight != null) {
            bounds = drawableRight.getBounds();
            if (x >= (this.getRight() - bounds.width() - fuzz) && x <= (this.getRight() - this.getPaddingRight() + fuzz) 
                  && y >= (this.getPaddingTop() - fuzz) && y <= (this.getHeight() - this.getPaddingBottom()) + fuzz) {
    
              clickListener.onClick(DrawableClickListener.DrawablePosition.RIGHT);
              if (consumeEvent) {
                event.setAction(MotionEvent.ACTION_CANCEL);
                return false;
              }
            }
          } else if (drawableTop != null) {
            // not impl reader exercise :)
          } else if (drawableBottom != null) {
            // not impl reader exercise :)
          }
        }
    
        return super.onTouchEvent(event);
      }
    
      @Override
      protected void finalize() throws Throwable {
        drawableRight = null;
        drawableBottom = null;
        drawableLeft = null;
        drawableTop = null;
        super.finalize();
      }
    
      public void setDrawableClickListener(DrawableClickListener listener) {
        this.clickListener = listener;
      }
    }
    
    package com.example.android;
    导入android.content.Context;
    导入android.graphics.drawable.drawable;
    导入android.util.AttributeSet;
    导入android.util.Log;
    导入android.view.MotionEvent;
    导入android.widget.EditText;
    导入android.graphics.Rect;
    导入com.example.android.DrawableClickListener;
    公共类ClickableButtoneDocument扩展了EditText{
    public static final String LOG_TAG=“ClickableButtonEditText”;
    私人提款权;
    私人可提取左;
    私人可拉丝上衣;
    私人可拉深底;
    私有事件=false;
    私有int fuzz=0;
    私有Drawable clickListener clickListener;
    公共ClickableButtonEditText(上下文上下文、属性集属性、int-defStyle){
    超级(上下文、属性、定义样式);
    }
    公共ClickableButtonEditText(上下文上下文、属性集属性){
    超级(上下文,attrs);
    }
    公共可点击按钮文本(上下文){
    超级(上下文);
    }
    公共事件(){
    此.setConsumeEvent(true);
    }
    公共无效setConsumeEvent(布尔b){
    this.consumerevent=b;
    }
    公共void setFuzz(intz){
    这个.fuzz=z;
    }
    public int getFuzz(){
    返回模糊;
    }
    @凌驾
    公共空隙设置复合可拉伸(可拉伸左侧、可拉伸顶部、可拉伸右侧、可拉伸底部){
    if(右!=null){
    可提取右=右;
    }
    if(左!=null){
    drawableLeft=左;
    }
    super.setCompoundDrawables(左、上、右、下);
    }
    @凌驾
    公共布尔onTouchEvent(运动事件){
    if(event.getAction()==MotionEvent.ACTION\u向下){
    int x,y;
    矩形边界;
    x=(int)event.getX();
    y=(int)event.getY();
    //这适用于left,因为容器与边界共享0,0原点
    如果(drawableLeft!=null){
    bounds=drawableLeft.getBounds();
    if(bounds.contains(x-fuzz,y-fuzz)){
    clickListener.onClick(DrawableClickListener.DrawablePosition.LEFT);
    如果(消费事件){
    event.setAction(MotionEvent.ACTION\u CANCEL);
    返回false;
    }
    }
    }else if(drawableRight!=null){
    bounds=drawableRight.getBounds();
    
    如果(x>=(this.getRight()-bounds.width()-fuzz)&&x=(this.getPaddingTop()-fuzz)&&y非常非常好,感谢所有参与讨论的人。因此,如果您不想处理扩展类带来的不便,您可以执行以下操作(仅针对右侧可绘制对象实现)

    下面是基于@Mark答案的基本侦听器实现

    public abstract class RightDrawableOnTouchListener implements OnTouchListener {
        Drawable drawable;
        private int fuzz = 10;
    
        /**
         * @param keyword
         */
        public RightDrawableOnTouchListener(TextView view) {
            super();
            final Drawable[] drawables = view.getCompoundDrawables();
            if (drawables != null && drawables.length == 4)
                this.drawable = drawables[2];
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see android.view.View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent)
         */
        @Override
        public boolean onTouch(final View v, final MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN && drawable != null) {
                final int x = (int) event.getX();
                final int y = (int) event.getY();
                final Rect bounds = drawable.getBounds();
                if (x >= (v.getRight() - bounds.width() - fuzz) && x <= (v.getRight() - v.getPaddingRight() + fuzz)
                        && y >= (v.getPaddingTop() - fuzz) && y <= (v.getHeight() - v.getPaddingBottom()) + fuzz) {
                    return onDrawableTouch(event);
                }
            }
            return false;
        }
    
        public abstract boolean onDrawableTouch(final MotionEvent event);
    
    }
    
    公共抽象类RightDrawableOnTouchListener实现OnTouchListener{
    可拉伸;
    私有int fuzz=10;
    /**
    *@param关键字
    */
    public RightDrawableOnTouchListener(文本视图){
    超级();
    最终可绘制[]可绘制=view.getCompo
    
    this.keyword = (AutoCompleteTextView) findViewById(R.id.search);
    this.keyword.setOnTouchListener(new RightDrawableOnTouchListener(keyword) {
            @Override
            public boolean onDrawableTouch(final MotionEvent event) {
                return onClickSearch(keyword,event);
            }
        });
    
    private boolean onClickSearch(final View view, MotionEvent event) {
        // do something
        event.setAction(MotionEvent.ACTION_CANCEL);
        return false;
    }
    
    public abstract class RightDrawableOnTouchListener implements OnTouchListener {
        Drawable drawable;
        private int fuzz = 10;
    
        /**
         * @param keyword
         */
        public RightDrawableOnTouchListener(TextView view) {
            super();
            final Drawable[] drawables = view.getCompoundDrawables();
            if (drawables != null && drawables.length == 4)
                this.drawable = drawables[2];
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see android.view.View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent)
         */
        @Override
        public boolean onTouch(final View v, final MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN && drawable != null) {
                final int x = (int) event.getX();
                final int y = (int) event.getY();
                final Rect bounds = drawable.getBounds();
                if (x >= (v.getRight() - bounds.width() - fuzz) && x <= (v.getRight() - v.getPaddingRight() + fuzz)
                        && y >= (v.getPaddingTop() - fuzz) && y <= (v.getHeight() - v.getPaddingBottom()) + fuzz) {
                    return onDrawableTouch(event);
                }
            }
            return false;
        }
    
        public abstract boolean onDrawableTouch(final MotionEvent event);
    
    }
    
    @Override
        public boolean onTouch(View v, MotionEvent event) {
    
            Drawable drawableObj = getResources().getDrawable(R.drawable.search_btn);
            int drawableWidth = drawableObj.getIntrinsicWidth();
    
            int x = (int) event.getX();
            int y = (int) event.getY();
    
            if (event != null && event.getAction() == MotionEvent.ACTION_UP) {
                if (x >= (searchPanel_search.getWidth() - drawableWidth - searchPanel_search.getPaddingRight())
                        && x <= (searchPanel_search.getWidth() - searchPanel_search.getPaddingRight())
    
                        && y >= searchPanel_search.getPaddingTop() && y <= (searchPanel_search.getHeight() - searchPanel_search.getPaddingBottom())) {
    
                    getSearchData();
                }
    
                else {
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.showSoftInput(searchPanel_search, InputMethodManager.SHOW_FORCED);
                }
            }
            return super.onTouchEvent(event);
    
        }
    
    editComment.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            final int DRAWABLE_LEFT = 0;
            final int DRAWABLE_TOP = 1;
            final int DRAWABLE_RIGHT = 2;
            final int DRAWABLE_BOTTOM = 3;
    
            if(event.getAction() == MotionEvent.ACTION_UP) {
                if(event.getRawX() >= (editComment.getRight() - editComment.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
                    // your action here
    
                    return true;
                }
            }
            return false;
        }
    });
    
    if(event.getRawX() <= (editComment.getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width())) 
    
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <TextView
            android:id="@+id/myTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="replace this with a variable"
            android:textSize="30sp"
            android:drawableLeft="@drawable/my_left_image"
            android:drawableRight="@drawable/my_right_image"
            android:drawablePadding="9dp" />
    
    </RelativeLayout>
    
    package com.company.project.core;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.TextView;
    
    public class MyActivity extends Activity
    {
    
        @Override
        protected void onCreate( Bundle savedInstanceState )
        {
            super.onCreate( savedInstanceState );
            setContentView( R.layout.activity_my );
    
            final TextView myTextView = (TextView) this.findViewById( R.id.myTextView );
            myTextView.setOnTouchListener( new DrawableClickListener.LeftDrawableClickListener(myTextView)
            {
                @Override
                public boolean onDrawableClick()
                {
                    // TODO : insert code to perform on clicking of the LEFT drawable image...
    
                    return true;
                }
            } );
            myTextView.setOnTouchListener( new DrawableClickListener.RightDrawableClickListener(myTextView)
            {
                @Override
                public boolean onDrawableClick()
                {
                    // TODO : insert code to perform on clicking of the RIGHT drawable image...
    
                    return true;
                }
            } );
        }
    
    }
    
    package com.company.project.core;
    
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.widget.TextView;
    
    /**
     * This class can be used to define a listener for a compound drawable.
     * 
     * @author Matthew Weiler
     * */
    public abstract class DrawableClickListener implements OnTouchListener
    {
    
        /* PUBLIC CONSTANTS */
        /**
         * This represents the left drawable.
         * */
        public static final int DRAWABLE_INDEX_LEFT = 0;
        /**
         * This represents the top drawable.
         * */
        public static final int DRAWABLE_INDEX_TOP = 1;
        /**
         * This represents the right drawable.
         * */
        public static final int DRAWABLE_INDEX_RIGHT = 2;
        /**
         * This represents the bottom drawable.
         * */
        public static final int DRAWABLE_INDEX_BOTTOM = 3;
        /**
         * This stores the default value to be used for the
         * {@link DrawableClickListener#fuzz}.
         * */
        public static final int DEFAULT_FUZZ = 10;
    
        /* PRIVATE VARIABLES */
        /**
         * This stores the number of pixels of &quot;fuzz&quot; that should be
         * included to account for the size of a finger.
         * */
        private final int fuzz;
        /**
         * This will store a reference to the {@link Drawable}.
         * */
        private Drawable drawable = null;
    
        /* CONSTRUCTORS */
        /**
         * This will create a new instance of a {@link DrawableClickListener}
         * object.
         * 
         * @param view
         *            The {@link TextView} that this {@link DrawableClickListener}
         *            is associated with.
         * @param drawableIndex
         *            The index of the drawable that this
         *            {@link DrawableClickListener} pertains to.
         *            <br />
         *            <i>use one of the values:
         *            <b>DrawableOnTouchListener.DRAWABLE_INDEX_*</b></i>
         */
        public DrawableClickListener( final TextView view, final int drawableIndex )
        {
            this( view, drawableIndex, DrawableClickListener.DEFAULT_FUZZ );
        }
    
        /**
         * This will create a new instance of a {@link DrawableClickListener}
         * object.
         * 
         * @param view
         *            The {@link TextView} that this {@link DrawableClickListener}
         *            is associated with.
         * @param drawableIndex
         *            The index of the drawable that this
         *            {@link DrawableClickListener} pertains to.
         *            <br />
         *            <i>use one of the values:
         *            <b>DrawableOnTouchListener.DRAWABLE_INDEX_*</b></i>
         * @param fuzzOverride
         *            The number of pixels of &quot;fuzz&quot; that should be
         *            included to account for the size of a finger.
         */
        public DrawableClickListener( final TextView view, final int drawableIndex, final int fuzz )
        {
            super();
            this.fuzz = fuzz;
            final Drawable[] drawables = view.getCompoundDrawables();
            if ( drawables != null && drawables.length == 4 )
            {
                this.drawable = drawables[drawableIndex];
            }
        }
    
        /* OVERRIDDEN PUBLIC METHODS */
        @Override
        public boolean onTouch( final View v, final MotionEvent event )
        {
            if ( event.getAction() == MotionEvent.ACTION_DOWN && drawable != null )
            {
                final int x = (int) event.getX();
                final int y = (int) event.getY();
                final Rect bounds = drawable.getBounds();
                if ( this.isClickOnDrawable( x, y, v, bounds, this.fuzz ) )
                {
                    return this.onDrawableClick();
                }
            }
            return false;
        }
    
        /* PUBLIC METHODS */
        /**
         * 
         * */
        public abstract boolean isClickOnDrawable( final int x, final int y, final View view, final Rect drawableBounds, final int fuzz );
    
        /**
         * This method will be fired when the drawable is touched/clicked.
         * 
         * @return
         *         <code>true</code> if the listener has consumed the event;
         *         <code>false</code> otherwise.
         * */
        public abstract boolean onDrawableClick();
    
        /* PUBLIC CLASSES */
        /**
         * This class can be used to define a listener for a <b>LEFT</b> compound
         * drawable.
         * */
        public static abstract class LeftDrawableClickListener extends DrawableClickListener
        {
    
            /* CONSTRUCTORS */
            /**
             * This will create a new instance of a
             * {@link LeftDrawableClickListener} object.
             * 
             * @param view
             *            The {@link TextView} that this
             *            {@link LeftDrawableClickListener} is associated with.
             */
            public LeftDrawableClickListener( final TextView view )
            {
                super( view, DrawableClickListener.DRAWABLE_INDEX_LEFT );
            }
    
            /**
             * This will create a new instance of a
             * {@link LeftDrawableClickListener} object.
             * 
             * @param view
             *            The {@link TextView} that this
             *            {@link LeftDrawableClickListener} is associated with.
             * @param fuzzOverride
             *            The number of pixels of &quot;fuzz&quot; that should be
             *            included to account for the size of a finger.
             */
            public LeftDrawableClickListener( final TextView view, final int fuzz )
            {
                super( view, DrawableClickListener.DRAWABLE_INDEX_LEFT, fuzz );
            }
    
            /* PUBLIC METHODS */
            public boolean isClickOnDrawable( final int x, final int y, final View view, final Rect drawableBounds, final int fuzz )
            {
                if ( x >= ( view.getPaddingLeft() - fuzz ) )
                {
                    if ( x <= ( view.getPaddingLeft() + drawableBounds.width() + fuzz ) )
                    {
                        if ( y >= ( view.getPaddingTop() - fuzz ) )
                        {
                            if ( y <= ( view.getHeight() - view.getPaddingBottom() + fuzz ) )
                            {
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
    
        }
    
        /**
         * This class can be used to define a listener for a <b>TOP</b> compound
         * drawable.
         * */
        public static abstract class TopDrawableClickListener extends DrawableClickListener
        {
    
            /* CONSTRUCTORS */
            /**
             * This will create a new instance of a {@link TopDrawableClickListener}
             * object.
             * 
             * @param view
             *            The {@link TextView} that this
             *            {@link TopDrawableClickListener} is associated with.
             */
            public TopDrawableClickListener( final TextView view )
            {
                super( view, DrawableClickListener.DRAWABLE_INDEX_TOP );
            }
    
            /**
             * This will create a new instance of a {@link TopDrawableClickListener}
             * object.
             * 
             * @param view
             *            The {@link TextView} that this
             *            {@link TopDrawableClickListener} is associated with.
             * @param fuzzOverride
             *            The number of pixels of &quot;fuzz&quot; that should be
             *            included to account for the size of a finger.
             */
            public TopDrawableClickListener( final TextView view, final int fuzz )
            {
                super( view, DrawableClickListener.DRAWABLE_INDEX_TOP, fuzz );
            }
    
            /* PUBLIC METHODS */
            public boolean isClickOnDrawable( final int x, final int y, final View view, final Rect drawableBounds, final int fuzz )
            {
                if ( x >= ( view.getPaddingLeft() - fuzz ) )
                {
                    if ( x <= ( view.getWidth() - view.getPaddingRight() + fuzz ) )
                    {
                        if ( y >= ( view.getPaddingTop() - fuzz ) )
                        {
                            if ( y <= ( view.getPaddingTop() + drawableBounds.height() + fuzz ) )
                            {
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
    
        }
    
        /**
         * This class can be used to define a listener for a <b>RIGHT</b> compound
         * drawable.
         * */
        public static abstract class RightDrawableClickListener extends DrawableClickListener
        {
    
            /* CONSTRUCTORS */
            /**
             * This will create a new instance of a
             * {@link RightDrawableClickListener} object.
             * 
             * @param view
             *            The {@link TextView} that this
             *            {@link RightDrawableClickListener} is associated with.
             */
            public RightDrawableClickListener( final TextView view )
            {
                super( view, DrawableClickListener.DRAWABLE_INDEX_RIGHT );
            }
    
            /**
             * This will create a new instance of a
             * {@link RightDrawableClickListener} object.
             * 
             * @param view
             *            The {@link TextView} that this
             *            {@link RightDrawableClickListener} is associated with.
             * @param fuzzOverride
             *            The number of pixels of &quot;fuzz&quot; that should be
             *            included to account for the size of a finger.
             */
            public RightDrawableClickListener( final TextView view, final int fuzz )
            {
                super( view, DrawableClickListener.DRAWABLE_INDEX_RIGHT, fuzz );
            }
    
            /* PUBLIC METHODS */
            public boolean isClickOnDrawable( final int x, final int y, final View view, final Rect drawableBounds, final int fuzz )
            {
                if ( x >= ( view.getWidth() - view.getPaddingRight() - drawableBounds.width() - fuzz ) )
                {
                    if ( x <= ( view.getWidth() - view.getPaddingRight() + fuzz ) )
                    {
                        if ( y >= ( view.getPaddingTop() - fuzz ) )
                        {
                            if ( y <= ( view.getHeight() - view.getPaddingBottom() + fuzz ) )
                            {
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
    
        }
    
        /**
         * This class can be used to define a listener for a <b>BOTTOM</b> compound
         * drawable.
         * */
        public static abstract class BottomDrawableClickListener extends DrawableClickListener
        {
    
            /* CONSTRUCTORS */
            /**
             * This will create a new instance of a
             * {@link BottomDrawableClickListener} object.
             * 
             * @param view
             *            The {@link TextView} that this
             *            {@link BottomDrawableClickListener} is associated with.
             */
            public BottomDrawableClickListener( final TextView view )
            {
                super( view, DrawableClickListener.DRAWABLE_INDEX_BOTTOM );
            }
    
            /**
             * This will create a new instance of a
             * {@link BottomDrawableClickListener} object.
             * 
             * @param view
             *            The {@link TextView} that this
             *            {@link BottomDrawableClickListener} is associated with.
             * @param fuzzOverride
             *            The number of pixels of &quot;fuzz&quot; that should be
             *            included to account for the size of a finger.
             */
            public BottomDrawableClickListener( final TextView view, final int fuzz )
            {
                super( view, DrawableClickListener.DRAWABLE_INDEX_BOTTOM, fuzz );
            }
    
            /* PUBLIC METHODS */
            public boolean isClickOnDrawable( final int x, final int y, final View view, final Rect drawableBounds, final int fuzz )
            {
                if ( x >= ( view.getPaddingLeft() - fuzz ) )
                {
                    if ( x <= ( view.getWidth() - view.getPaddingRight() + fuzz ) )
                    {
                        if ( y >= ( view.getHeight() - view.getPaddingBottom() - drawableBounds.height() - fuzz ) )
                        {
                            if ( y <= ( view.getHeight() - view.getPaddingBottom() + fuzz ) )
                            {
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
    
        }
    
    }
    
    <merge
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <EditText
            android:id="@+id/edit_text_field"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
        <!-- NOTE: Visibility cannot be set to "gone" or the padding won't get set properly in code -->
        <ImageButton
            android:id="@+id/edit_text_clear"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right|center_vertical"
            android:background="@drawable/ic_cancel_x"
            android:visibility="invisible"/>
    </merge>
    
    public class ClearableEditText extends FrameLayout {
        private boolean mPaddingSet = false;
    
        /**
         * Creates a new instance of this class.
         * @param context The context used to create the instance
         */
        public ClearableEditText (final Context context) {
            this(context, null, 0);
        }
    
        /**
         * Creates a new instance of this class.
         * @param context The context used to create the instance
         * @param attrs The attribute set used to customize this instance
         */
        public ClearableEditText (final Context context, final AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        /**
         * Creates a new instance of this class.
         * @param context The context used to create the instance
         * @param attrs The attribute set used to customize this instance
         * @param defStyle The default style to be applied to this instance
         */
        public ClearableEditText (final Context context, final AttributeSet attrs, final int defStyle) {
            super(context, attrs, defStyle);
    
            final LayoutInflater inflater = LayoutInflater.from(context);
            inflater.inflate(R.layout.clearable_edit_text, this, true);
        }
    
        @Override
        protected void onFinishInflate () {
            super.onFinishInflate();
    
            final EditText editField = (EditText) findViewById(R.id.edit_text_field);
            final ImageButton clearButton = (ImageButton) findViewById(R.id.edit_text_clear);
    
            //Set text listener so we can show/hide the close button based on whether or not it has text
            editField.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged (final CharSequence charSequence, final int i, final int i2, final int i3) {
                    //Do nothing here
                }
    
                @Override
                public void onTextChanged (final CharSequence charSequence, final int i, final int i2, final int i3) {
                    //Do nothing here
                }
    
                @Override
                public void afterTextChanged (final Editable editable) {
                    clearButton.setVisibility(editable.length() > 0 ? View.VISIBLE : View.INVISIBLE);
                }
            });
    
            //Set the click listener for the button to clear the text. The act of clearing the text will hide this button because of the
            //text listener
            clearButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick (final View view) {
                    editField.setText("");
                }
            });
        }
    
        @Override
        protected void onLayout (final boolean changed, final int left, final int top, final int right, final int bottom) {
            super.onLayout(changed, left, top, right, bottom);
    
            //Set padding here in the code so the text doesn't run into the close button. This could be done in the XML layout, but then if
            //the size of the image changes then we constantly need to tweak the padding when the image changes. This way it happens automatically
            if (!mPaddingSet) {
                final EditText editField = (EditText) findViewById(R.id.edit_text_field);
                final ImageButton clearButton = (ImageButton) findViewById(R.id.edit_text_clear);
    
                editField.setPadding(editField.getPaddingLeft(), editField.getPaddingTop(), clearButton.getWidth(), editField.getPaddingBottom());
                mPaddingSet = true;
            }
        }
    }
    
    <RelativeLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content">
    
      <EditText android:id="@+id/editTextName"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:imeOptions="actionSearch"
        android:inputType="text"/>
    
      <ImageButton android:id="@+id/imageViewSearch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_action_search"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"/>
    
    </RelativeLayout>
    
    <FrameLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="5dp" >
    
                <EditText
                    android:id="@+id/edt_status_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="10dp"
                    android:background="@drawable/txt_box_blank"
                    android:ems="10"
                    android:hint="@string/statusnote"
                    android:paddingLeft="5dp"
                    android:paddingRight="10dp"
                    android:textColor="@android:color/black" />
    
                <Button
                    android:id="@+id/note_del"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="right"
                    android:layout_marginRight="1dp"
                    android:layout_marginTop="5dp"
                    android:background="@android:drawable/ic_delete" />
            </FrameLayout>
    
    EditText txtsearch = (EditText) findViewById(R.id.txtsearch);
    txtsearch.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_UP) {
                if(event.getRawX() <= txtsearch.getTotalPaddingLeft()) {
                    // your action for drawable click event
    
                 return true;
                }
            }
            return false;
        }
    });
    
    if(event.getRawX() >= txtsearch.getRight() - txtsearch.getTotalPaddingRight())
    
    txtsearch.getTotalPaddingTop()
    txtsearch.getTotalPaddingBottom()
    
    mEditTextSearch.addTextChangedListener(new TextWatcher() {
    
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if(s.length()>0){
                    mEditTextSearch.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(android.R.drawable.ic_delete), null);
                }else{
                    mEditTextSearch.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(R.drawable.abc_ic_search), null);
                }
            }
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
            @Override
            public void afterTextChanged(Editable s) {
            }
        });
        mEditTextSearch.setOnTouchListener(new OnTouchListener() {
            @SuppressLint("ClickableViewAccessibility")
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(event.getAction() == MotionEvent.ACTION_UP) {
                    if(mEditTextSearch.getCompoundDrawables()[2]!=null){
                        if(event.getX() >= (mEditTextSearch.getRight()- mEditTextSearch.getLeft() - mEditTextSearch.getCompoundDrawables()[2].getBounds().width())) {
                            mEditTextSearch.setText("");
                        }
                    }
                }
                return false;
            }
        });
    
     editComment.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                final int DRAWABLE_LEFT = 0;
                final int DRAWABLE_TOP = 1;
                final int DRAWABLE_RIGHT = 2;
                final int DRAWABLE_BOTTOM = 3;
    
                if(event.getAction() == MotionEvent.ACTION_UP) {
                    if (event.getRawX() <= (searchbox.getLeft() + searchbox.getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width())) {
                                         // your action here
    
                     return true;
                    }
                }
                return false;
            }
        });
    
    txt.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                final int DRAWABLE_LEFT = 0;
    
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    if (event.getRawX() <= (txt
                            .getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width() +
                            txt.getPaddingLeft() +
                            txt.getLeft())) {
    
                              //TODO do code here
                        }
                        return true;
                    }
                }
                return false;
            }
        });
    
        <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/zero_row">
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="wrap_content"
                android:layout_height="match_parent">
                <ProgressBar
                    android:id="@+id/loadingProgressBar"
                    android:layout_gravity="center"
                    android:layout_width="28dp"
                    android:layout_height="28dp" />
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:background="@drawable/edittext_round_corners"
                android:layout_height="match_parent"
                android:layout_marginLeft="5dp">
                <ImageView
                    android:layout_width="28dp"
                    android:layout_height="28dp"
                    app:srcCompat="@android:drawable/ic_menu_search"
                    android:id="@+id/imageView2"
                    android:layout_weight="0.15"
                    android:layout_gravity="center|right"
                    android:onClick="OnDatabaseSearchEvent" />
                <EditText
                    android:minHeight="40dp"
                    android:layout_marginLeft="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/edittext_round_corners"
                    android:inputType="textPersonName"
                    android:hint="Search.."
                    android:textColorHint="@color/AndroidWhite"
                    android:textColor="@color/AndroidWhite"
                    android:ems="10"
                    android:id="@+id/e_d_search"
                    android:textCursorDrawable="@color/AndroidWhite"
                    android:layout_weight="1" />
                <ImageView
                    android:layout_width="28dp"
                    android:layout_height="28dp"
                    app:srcCompat="@drawable/ic_oculi_remove2"
                    android:id="@+id/imageView3"
                    android:layout_gravity="center|left"
                    android:layout_weight="0.15"
                    android:onClick="onSearchEditTextCancel" />
            </LinearLayout>
    
            <!--android:drawableLeft="@android:drawable/ic_menu_search"-->
            <!--android:drawableRight="@drawable/ic_oculi_remove2"-->
    
        </LinearLayout>
    
    </LinearLayout>
    
    <item android:state_pressed="false" android:state_focused="false">
        <shape>
            <gradient
                android:centerY="0.2"
                android:startColor="@color/colorAccent"
                android:centerColor="@color/colorAccent"
                android:endColor="@color/colorAccent"
                android:angle="270"
                />
            <stroke
                android:width="0.7dp"
                android:color="@color/colorAccent" />
            <corners
                android:radius="5dp" />
        </shape>
    </item>
    
    txtsearch.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                final int DRAWABLE_LEFT = 0;
                int start=txtsearch.getSelectionStart();
                int end=txtsearch.getSelectionEnd();
                if(event.getAction() == MotionEvent.ACTION_UP) {
                    if(event.getRawX() <= (txtsearch.getLeft() + txtsearch.getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width())) {
                        //Do your action here
                        return true;
                    }
    
                }
                return false;
            }
        });
    }
    
    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:background="@color/white"
            android:layout_marginLeft="20dp"
            android:layout_marginStart="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginEnd="20dp"
            android:layout_gravity="center_horizontal"
            android:orientation="horizontal"
            android:translationZ="4dp">
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:background="@color/white"
                android:minWidth="40dp"
                android:scaleType="center"
                app:srcCompat="@drawable/ic_search_map"/>
    
            <android.support.design.widget.TextInputEditText
                android:id="@+id/search_edit"
                style="@style/EditText.Registration.Map"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:hint="@string/hint_location_search"
                android:imeOptions="actionSearch"
                android:inputType="textPostalAddress"
                android:maxLines="1"
                android:minHeight="40dp" />
    
            <ImageView
                android:id="@+id/location_gps_refresh"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:background="@color/white"
                android:minWidth="40dp"
                android:scaleType="center"
                app:srcCompat="@drawable/selector_ic_gps"/>
    </LinearLayout>
    
    editText.Touch += (sender, e) => {
                        e.Handled = false;
                        if (e.Event.Action == MotionEventActions.Up)
                        {
                            if (e.Event.RawX >= (bibEditText.Right - (bibEditText.GetCompoundDrawables()[2]).Bounds.Width()))
                            {
                                SearchRunner();
                                InputMethodManager manager = (InputMethodManager)GetSystemService(InputMethodService);
                                manager.HideSoftInputFromWindow(editText.WindowToken, 0);
                                e.Handled = true;
                            }
                        }
                    };
    
    editMsg.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                final int DRAWABLE_LEFT = 0;
                final int DRAWABLE_TOP = 1;
                final int DRAWABLE_RIGHT = 2;
                final int DRAWABLE_BOTTOM = 3;
    
                if(event.getAction() == MotionEvent.ACTION_UP) {
                    if(event.getRawX() >= (editMsg.getRight() - editMsg.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
                        // your action here
    
                        Toast.makeText(ChatActivity.this, "Message Sent", Toast.LENGTH_SHORT).show();
                        return true;
                    }
                }
                return false;
            }
        });
    
    /**
     * Handles compound drawable touch events.
     * Will intercept every event that happened inside (calculated) compound drawable bounds, extended by fuzz.
     * @see TextView#getCompoundDrawables()
     * @see TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(int, int, int, int)
     */
    public abstract class CompoundDrawableTouchListener implements View.OnTouchListener {
    
        private final String LOG_TAG = "CmpDrawableTouch";
    
        private final int fuzz;
    
        public static final int LEFT = 0;
        public static final int TOP = 1;
        public static final int RIGHT = 2;
        public static final int BOTTOM = 3;
        private static final int[] DRAWABLE_INDEXES = {LEFT, TOP, RIGHT, BOTTOM};
    
        /**
         * Default constructor
         */
        public CompoundDrawableTouchListener() {
            this(0);
        }
    
        /**
         * Constructor with fuzz
         * @param fuzz desired fuzz in px
         */
        public CompoundDrawableTouchListener(int fuzz) {
            this.fuzz = fuzz;
        }
    
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            if (!(view instanceof TextView)) {
                Log.e(LOG_TAG, "attached view is not instance of TextView");
                return false;
            }
    
            TextView textView = (TextView) view;
            Drawable[] drawables = textView.getCompoundDrawables();
            int x = (int) event.getX();
            int y = (int) event.getY();
    
            for (int i : DRAWABLE_INDEXES) {
                if (drawables[i] == null) continue;
                Rect bounds = getRelativeBounds(i, drawables[i], textView);
                Rect fuzzedBounds = addFuzz(bounds);
    
                if (fuzzedBounds.contains(x, y)) {
                    MotionEvent relativeEvent = MotionEvent.obtain(
                        event.getDownTime(),
                        event.getEventTime(),
                        event.getAction(),
                        event.getX() - bounds.left,
                        event.getY() - bounds.top,
                        event.getMetaState());
                    return onDrawableTouch(view, i, bounds, relativeEvent);
                }
            }
    
            return false;
        }
    
        /**
         * Calculates compound drawable bounds relative to wrapping view
         * @param index compound drawable index
         * @param drawable the drawable
         * @param view wrapping view
         * @return {@link Rect} with relative bounds
         */
        private Rect getRelativeBounds(int index, @NonNull Drawable drawable, View view) {
            Rect drawableBounds = drawable.getBounds();
            Rect bounds = new Rect();
    
            switch (index) {
                case LEFT:
                    bounds.offsetTo(view.getPaddingLeft(),
                        view.getHeight() / 2 - bounds.height() / 2);
                    break;
    
                case TOP:
                    bounds.offsetTo(view.getWidth() / 2 - bounds.width() / 2,
                        view.getPaddingTop());
                    break;
    
                case RIGHT:
                    bounds.offsetTo(view.getWidth() - view.getPaddingRight() - bounds.width(),
                        view.getHeight() / 2 - bounds.height() / 2);
                    break;
    
                case BOTTOM:
                    bounds.offsetTo(view.getWidth() / 2 - bounds.width() / 2,
                        view.getHeight() - view.getPaddingBottom() - bounds.height());
                    break;
            }
    
            return bounds;
        }
    
        /**
         * Expands {@link Rect} by given value in every direction relative to its center
         * @param source given {@link Rect}
         * @return result {@link Rect}
         */
        private Rect addFuzz(Rect source) {
            Rect result = new Rect();
            result.left = source.left - fuzz;
            result.right = source.right + fuzz;
            result.top = source.top - fuzz;
            result.bottom = source.bottom + fuzz;
            return result;
        }
    
        /**
         * Compound drawable touch-event handler
         * @param v wrapping view
         * @param drawableIndex index of compound drawable which recicved the event
         * @param drawableBounds {@link Rect} with compound drawable bounds relative to wrapping view.
         * Fuzz not included
         * @param event event with coordinated relative to wrapping view - i.e. within {@code drawableBounds}.
         * If using fuzz, may return negative coordinates.
         */
        protected abstract boolean onDrawableTouch(View v, int drawableIndex, Rect drawableBounds, MotionEvent event);
    }
    
    textView1.setOnTouchListener(new CompoundDrawableTouchListener() {
                @Override
                protected void onDrawableTouch(View v, int drawableIndex, Rect drawableBounds, MotionEvent event) {
                    switch(v.getId()) {
                        case R.id.textView1:
                            switch(drawableIndex) {
                                case CompoundDrawableTouchListener.RIGHT:
                                    doStuff();
                                    break;
                            }
                            break;
                    }
                }
            });
    
    /**
     * Handles compound drawable click events.
     * @see TextView#getCompoundDrawables()
     * @see TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(int, int, int, int)
     * @see CompoundDrawableTouchListener
     */
    public abstract class CompoundDrawableClickListener extends CompoundDrawableTouchListener {
    
        /**
         * Default constructor
         */
        public CompoundDrawableClickListener() {
            super();
        }
    
         /**
         * Constructor with fuzz
         * @param fuzz desired fuzz in px
         */
        public CompoundDrawableClickListener(int fuzz) {
            super(fuzz);
        }
    
        @Override
        protected void onDrawableTouch(View v, int drawableIndex, Rect drawableBounds, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) onDrawableClick(v, drawableIndex);
            return true;
        }
    
        /**
         * Compound drawable touch-event handler
         * @param v wrapping view
         * @param drawableIndex index of compound drawable which recicved the event
         */
        protected abstract void onDrawableClick(View v, int drawableIndex);
    }
    
    textView1.setOnTouchListener(new CompoundDrawableClickListener() {
                @Override
                protected void onDrawableClick(View v, int drawableIndex) {
                    switch(v.getId()) {
                        case R.id.textView1:
                            switch(drawableIndex) {
                                case CompoundDrawableTouchListener.RIGHT:
                                    doStuff();
                                    break;
                            }
                            break;
                    }
                }
            });
    
      <RelativeLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content">
    
       <android.support.design.widget.TextInputLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content">
    
         <android.support.design.widget.TextInputEditText
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
          />
         </android.support.design.widget.TextInputLayout>
         <ImageView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_alignParentEnd="true"
           android:layout_centerInParent="true"
           android:src="@drawable/ic_undo"/>
        </RelativeLayout>
    
    edit_account_name.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    if (event.getRawX() >= (edit_account_name.getRight())) {
                        //clicked
                       return true;
                    }
                }
                return false;
            }
        });
    
    mEditText.setOnTouchListener(
            new OnEditTextRightDrawableTouchListener(mEditText) {
              @Override
              public void OnDrawableClick() {
                // The right drawable was clicked. Your action goes here.
              }
            });
    
    import android.graphics.drawable.Drawable;
    import android.support.annotation.NonNull;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.widget.EditText;
    
    public abstract class OnEditTextRightDrawableTouchListener implements OnTouchListener {
    
      private final EditText mEditText;
    
      public OnEditTextRightDrawableTouchListener(@NonNull final EditText editText) {
        mEditText = editText;
      }
    
      @Override
      public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
          final int DRAWABLE_RIGHT_POSITION = 2;
          final Drawable drawable = mEditText.getCompoundDrawables()[DRAWABLE_RIGHT_POSITION];
          if (drawable != null) {
            final float touchEventX = motionEvent.getX();
            final int touchAreaRight = mEditText.getRight();
            final int touchAreaLeft = touchAreaRight - drawable.getBounds().width();
            if (touchEventX >= touchAreaLeft && touchEventX <= touchAreaRight) {
              view.performClick();
              OnDrawableClick();
            }
            return true;
          }
        }
        return false;
      }
    
      public abstract void OnDrawableClick();
    }
    
    edittextview_confirmpassword.setOnTouchListener(new View.OnTouchListener() {
        @Override        public boolean onTouch(View v, MotionEvent event) {
            final int DRAWABLE_LEFT = 0;
            final int DRAWABLE_TOP = 1;
            final int DRAWABLE_RIGHT = 2;
            final int DRAWABLE_BOTTOM = 3;
    
            if(event.getAction() == MotionEvent.ACTION_UP) {
                if(event.getRawX() >= (edittextview_confirmpassword.getRight() - edittextview_confirmpassword.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
                    // your action here                    edittextview_confirmpassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                    return true;
                }
            }else{
                edittextview_confirmpassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
    
            }
            return false;
        }
    });
    
    fun EditText.onRightDrawableClicked(onClicked: (view: EditText) -> Unit) {
    this.setOnTouchListener { v, event ->
        var hasConsumed = false
        if (v is EditText) {
            if (event.x >= v.width - v.totalPaddingRight) {
                if (event.action == MotionEvent.ACTION_UP) {
                    onClicked(this)
                }
                hasConsumed = true
            }
        }
        hasConsumed
    }
    }
    
    val username = findViewById<EditText>(R.id.username_text)
        username.onRightDrawableClicked {
            it.text.clear()
        }
    
    edPassword.setOnTouchListener { _, event ->
                val DRAWABLE_RIGHT = 2
                val DRAWABLE_LEFT = 0
                val DRAWABLE_TOP = 1
                val DRAWABLE_BOTTOM = 3
                if (event.action == MotionEvent.ACTION_UP) {
                    if (event.rawX >= (edPassword.right - edPassword.compoundDrawables[DRAWABLE_RIGHT].bounds.width())) {
                        edPassword.setText("")
                        true
                    }
                }
                false
            }
    
    @SuppressLint("ClickableViewAccessibility")
    fun EditText.setDrawableRightTouch(setClickListener: () -> Unit) {
        this.setOnTouchListener(View.OnTouchListener { _, event ->
            val DRAWABLE_LEFT = 0
            val DRAWABLE_TOP = 1
            val DRAWABLE_RIGHT = 2
            val DRAWABLE_BOTTOM = 3
            if (event.action == MotionEvent.ACTION_UP) {
                if (event.rawX >= this.right - this.compoundDrawables[DRAWABLE_RIGHT].bounds.width()
                ) {
                    setClickListener()
                    return@OnTouchListener true
                }
            }
            false
        })
    }
    
    yourEditText.setDrawableRightTouch {
        //your code
    }