Estableciendo onClickListner para el derecho Drawable de un EditText

En mi aplicación, tengo un EditText con un ícono de búsqueda en el lado derecho. Usé el código que figura a continuación.

   

Quiero configurar onClickListner para la imagen del icono de búsqueda asignada al EditText derecho de EditText . Como es posible ?

 public class CustomEditText extends EditText { private Drawable drawableRight; private Drawable drawableLeft; private Drawable drawableTop; private Drawable drawableBottom; int actionX, actionY; private DrawableClickListener clickListener; public CustomEditText (Context context, AttributeSet attrs) { super(context, attrs); // this Contructure required when you are using this view in xml } public CustomEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } protected void onDraw(Canvas canvas) { super.onDraw(canvas); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); } @Override public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) { if (left != null) { drawableLeft = left; } if (right != null) { drawableRight = right; } if (top != null) { drawableTop = top; } if (bottom != null) { drawableBottom = bottom; } super.setCompoundDrawables(left, top, right, bottom); } @Override public boolean onTouchEvent(MotionEvent event) { Rect bounds; if (event.getAction() == MotionEvent.ACTION_DOWN) { actionX = (int) event.getX(); actionY = (int) event.getY(); if (drawableBottom != null && drawableBottom.getBounds().contains(actionX, actionY)) { clickListener.onClick(DrawablePosition.BOTTOM); return super.onTouchEvent(event); } if (drawableTop != null && drawableTop.getBounds().contains(actionX, actionY)) { clickListener.onClick(DrawablePosition.TOP); return super.onTouchEvent(event); } // this works for left since container shares 0,0 origin with bounds if (drawableLeft != null) { bounds = null; bounds = drawableLeft.getBounds(); int x, y; int extraTapArea = (int) (13 * getResources().getDisplayMetrics().density + 0.5); x = actionX; y = actionY; if (!bounds.contains(actionX, actionY)) { /** Gives the +20 area for tapping. */ x = (int) (actionX - extraTapArea); y = (int) (actionY - extraTapArea); if (x <= 0) x = actionX; if (y <= 0) y = actionY; /** Creates square from the smallest value */ if (x < y) { y = x; } } if (bounds.contains(x, y) && clickListener != null) { clickListener .onClick(DrawableClickListener.DrawablePosition.LEFT); event.setAction(MotionEvent.ACTION_CANCEL); return false; } } if (drawableRight != null) { bounds = null; bounds = drawableRight.getBounds(); int x, y; int extraTapArea = 13; /** * IF USER CLICKS JUST OUT SIDE THE RECTANGLE OF THE DRAWABLE * THAN ADD X AND SUBTRACT THE Y WITH SOME VALUE SO THAT AFTER * CALCULATING X AND Y CO-ORDINATE LIES INTO THE DRAWBABLE * BOUND. - this process help to increase the tappable area of * the rectangle. */ x = (int) (actionX + extraTapArea); y = (int) (actionY - extraTapArea); /**Since this is right drawable subtract the value of x from the width * of view. so that width - tappedarea will result in x co-ordinate in drawable bound. */ x = getWidth() - x; /*x can be negative if user taps at x co-ordinate just near the width. * eg views width = 300 and user taps 290. Then as per previous calculation * 290 + 13 = 303. So subtract X from getWidth() will result in negative value. * So to avoid this add the value previous added when x goes negative. */ if(x <= 0){ x += extraTapArea; } /* If result after calculating for extra tappable area is negative. * assign the original value so that after subtracting * extratapping area value doesn't go into negative value. */ if (y <= 0) y = actionY; /**If drawble bounds contains the x and y points then move ahead.*/ if (bounds.contains(x, y) && clickListener != null) { clickListener .onClick(DrawableClickListener.DrawablePosition.RIGHT); event.setAction(MotionEvent.ACTION_CANCEL); return false; } return super.onTouchEvent(event); } } 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; } } 

También crea una interfaz con

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

Aún si necesitas ayuda, comenta

Configure también el drawableClickListener en la vista en el archivo de actividad.

 editText.setDrawableClickListener(new DrawableClickListener() { public void onClick(DrawablePosition target) { switch (target) { case LEFT: //Do something here break; default: break; } } }); 

Solución simple, use métodos que Android ya ha dado, en lugar de reinventar wheeeeeeeeeel 🙂

 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; } }); 

Esto ya ha sido respondido pero intenté una forma diferente de hacerlo más simple.

La idea es usar poner un ImageButton a la derecha de EditText y tener un margen negativo para que EditText fluya al ImageButton haciendo que parezca que el botón está en EditText .

enter image description here

      

Además, como se muestra arriba, puede usar un paddingRight de ancho similar en EditText si no desea que el texto en el mismo se ImageButton sobre el ImageButton .

Adiviné el tamaño del margen con la ayuda del diseñador de diseño de android-studio y se ve similar en todos los tamaños de pantalla. O bien, puede calcular el ancho del ImageButton y establecer el margen programáticamente.

No tiene acceso a la imagen correcta, según mi conocimiento, a menos que anule el evento onTouch . Sugiero usar un RelativeLayout , con un editText y un imageView , y establecer OnClickListener sobre la vista de la imagen como se muestra a continuación:

     

Sé que esto es bastante viejo, pero recientemente tuve que hacer algo muy similar, y se me ocurrió una solución mucho más simple.

Se reduce a los siguientes pasos:

  1. Crear un diseño XML que contenga EditText e Image
  2. Subclase FrameLayout e inflar el diseño XML
  3. Agregue código para el detector de clics y cualquier otro comportamiento que desee … sin tener que preocuparse por las posiciones del clic o cualquier otro código desordenado.

Consulte esta publicación para ver el ejemplo completo: Manejo de los eventos de clic en un dibujo dentro de un EditText

Por favor use el siguiente truco:

  • Cree un botón de imagen con su icono y establezca el color de fondo para que sea transparente.
  • Pon el botón de imagen en EditText
  • Implemente el oyente ‘onclic’k del botón para ejecutar su función