utilizar studio largo eventos evento crear como capturar boton android android-widget android-edittext compound-drawables

android - studio - Manejo de eventos de clic en un dibujo dentro de un EditText



on click listener android studio (30)

He añadido una imagen a la derecha del texto en un widget EditText , utilizando el siguiente XML:

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

Pero quiero borrar el texto de EditText cuando se hace clic en la imagen incrustada. ¿Cómo puedo hacer esto?


Ampliando la idea de RyanM, he creado una versión más flexible, que admite todos los tipos dibujables (arriba, abajo, izquierda, derecha). Mientras que el código a continuación extiende TextView, adaptarlo para un EditText es solo un caso de intercambio "extiende TextView" con "extiende EditText". La instanciación del widget desde XML es idéntica a la del ejemplo de RyanM, barra el nombre del widget.

import android.content.Context; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.TextView; import com.example.DrawableClickListener.DrawablePosition; public class ButtonTextView extends TextView { private Drawable drawableRight; private Drawable drawableLeft; private Drawable drawableTop; private Drawable drawableBottom; private int actionX, actionY; private DrawableClickListener clickListener; public ButtonTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public ButtonTextView(Context context, AttributeSet attrs) { super(context, attrs); } public ButtonTextView(Context context) { super(context); } @Override public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) { if (right != null) { drawableRight = right; } if (left != null) { drawableLeft = left; } if (top != null) { drawableTop = top; } if (bottom != null) { drawableBottom = bottom; } super.setCompoundDrawables(left, top, right, bottom); } @Override public boolean onTouchEvent(MotionEvent event) { 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); } if (drawableLeft != null && drawableLeft.getBounds().contains(actionX, actionY)) { clickListener.onClick(DrawablePosition.LEFT); return super.onTouchEvent(event); } if (drawableRight != null && drawableRight.getBounds().contains(actionX, actionY)) { clickListener.onClick(DrawablePosition.RIGHT); 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; }}

DrawableClickListener es tan simple como esto:

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

Y luego la implementación real:

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

ps: Si no configura la escucha, al tocar TextView se generará una NullPointerException. Es posible que desee agregar un poco más de paranoia en el código.


Considera lo siguiente. No es la solución más elegante, pero funciona, acabo de probarlo.

  1. Cree una clase personalizada de 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(); } }

  2. Cambie su diseño XML a esto (donde com.example es el nombre de su paquete de proyecto real):

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

  3. Finalmente, agregue esto (o algo similar) a su actividad:

    … CustomEditText et = (CustomEditText) this.findViewById(R.id.txtsearch); …

Puede que me falte un poco el cálculo de los límites táctiles para el dibujo anidado, pero entiendes la idea.

Espero que esto ayude.


Creo que es mucho más fácil si usamos algunos trucos :)

  1. Crea un botón de imagen con tu ícono y establece su color de fondo para que sea transparente .
  2. Ponga el botón de imagen en el texto de edición y, a continuación, en el lado derecho.
  3. Implemente el oyente onclick del botón para ejecutar su función

Hecho


El uso de la última contribución de contains(x,y) no funcionará directamente en el resultado de getBounds() (excepto, por coincidencia, cuando se usan elementos getBounds() "izquierda"). El método getBounds solo proporciona los puntos de definición de Rect del elemento Rect normalizados con el origen en 0,0, por lo que realmente necesita hacer los cálculos de la publicación original para averiguar si el clic está en el área del dibujo en el contexto. de las dimensiones de EditText que contiene, pero cámbiela por arriba, derecha, izquierda, etc. Alternativamente, podría describir un Rect que tiene coordenadas en realidad relativas a su posición en el contenedor EditText y use contains() , aunque al final está haciendo las mismas matematicas

Combinarlos a ambos le brinda una solución bastante completa, solo agregué un atributo de instancia consumesEvent que le permite al usuario de la API decidir si el evento de clic se debe transmitir o no al usar su resultado para configurar ACTION_CANCEL o no.

Además, no puedo ver por qué los bounds y actionX , actionY valores son atributos de instancia en lugar de solo locales en la pila.

Aquí hay un recorte de una implementación basada en lo anterior que armé. Se soluciona un problema que para consumir correctamente el evento que necesita devolver falso. Añade un factor "fuzz" a. En mi caso de uso de un ícono de control de Voz en un campo EditText , encontré difícil hacer clic, por lo que el fuzz aumenta los límites efectivos que se consideran hacer clic en el dibujo. Para mi 15 funcionó bien. Solo necesitaba drawableRight así que no conecté los cálculos en los demás para ahorrar espacio, pero ves la idea.

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


En realidad no necesitas extender ninguna clase. Digamos que tengo un EditText editComment con drawableRight

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

obtenemosRawX getRawX() porque queremos obtener la posición real del toque en la pantalla, no relativa a la matriz.

Para obtener click izquierdo

if(event.getRawX() <= (editComment.getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width()))


Es muy sencillo. Digamos que tiene un dibujo en el lado izquierdo de su ''Editor de texto'' txtsearch ''. Siguiente hará el truco.

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

Si quieres, por derecho, cambiar la instrucción if a:

if(event.getRawX() >= txtsearch.getRight() - txtsearch.getTotalPaddingRight())

Del mismo modo, puedes hacerlo para todos los dibujables compuestos.

txtsearch.getTotalPaddingTop() txtsearch.getTotalPaddingBottom()

Esta llamada al método devuelve todo el relleno en ese lado, incluidos los elementos dibujables. Puedes usar esto incluso para TextView, Button, etc.

Haga clic here para referencia del sitio del desarrollador de Android.


Muy, muy bien, gracias a todos los que contribuyeron a esta discusión. Por lo tanto, si no desea lidiar con los inconvenientes de extender la clase, puede hacer lo siguiente (implementado solo para el dibujo correcto)

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

Y aquí está la implementación de la escucha basada en la respuesta de @ 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); }


Sé que esto es bastante viejo, pero recientemente tuve que hacer algo similar ... Después de ver lo difícil que es esto, se me ocurrió una solución mucho más simple:

  1. Cree un diseño XML que contenga el texto e imagen de edición
  2. Subclase FrameLayout e infla el diseño XML
  3. Agregue código para el detector de clics y cualquier otro comportamiento que desee

En mi caso, necesitaba un EditText que tuviera la capacidad de borrar el texto con un botón. Quería que se pareciera a SearchView, pero por varias razones no quería usar esa clase. El siguiente ejemplo muestra cómo logré esto. Aunque no tiene que ver con el cambio de enfoque, los principios son los mismos y pensé que sería más beneficioso publicar el código de trabajo real que armar un ejemplo que puede no funcionar exactamente como lo quería

Aquí está mi diseño: clearable_edit_text.xml

<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>

Y aquí está la clase que infla ese diseño: ClearableEditText.java

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

Para hacer esta respuesta más en línea con la pregunta, se deben seguir los siguientes pasos:

  1. Cambia el recurso dibujable a lo que quieras ... En mi caso, era una X gris
  2. Agregar un oyente de cambio de enfoque al texto de edición ...

está funcionando para mí,

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


Creé una clase abstracta útil DrawableClickListener que implementa OnTouchListener .

Además de la clase DrawableClickListener , también creé 4 clases abstractas adicionales que extienden la clase DrawableClickListener y manejan el clic del área del dibujo para el cuadrante correcto.

  • LeftDrawableClickListener
  • TopDrawableClickListener
  • RightDrawableClickListener
  • BottomDrawableClickListener

Punto a considerar

Una cosa a considerar es que las imágenes no se redimensionan si se hacen de esta manera; por lo tanto, las imágenes se deben escalar correctamente antes de colocarlas en las carpetas res / drawable .

Si define un LinearLayout que contiene un ImageView y un TextView , es mucho más fácil manipular el tamaño de la imagen que se muestra.

actividad_my.xml

<?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>

MyActivity.java

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

DrawableClickListener.java

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


Siga el código de abajo para dibujar a la derecha, izquierda, arriba, abajo, haga clic:

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

}


para el oyente de clic izquierdo dibujable

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


Aplico una solución corta que es adecuada incluso para fragmentos de diálogo.

//The listener of a drawableEnd button for clear a TextInputEditText textValue.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onT[![enter image description here][1]][1]ouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_UP) { final TextView textView = (TextView)v; if(event.getX() >= textView.getWidth() - textView.getCompoundPaddingEnd()) { textView.setText(""); //Clear a view, example: EditText or TextView return true; } } return false; } });


Compartiendo mi solución generalizada para manejar eventos de toque y toque de TextView.

Primero necesitamos un controlador de eventos táctil:

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

Ahora puede procesar cualquier evento táctil en cualquier dibujo dibujable de cualquier TextView que le guste de esta manera:

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

Sólo interesado en clics? Simplemente filtre por acción de MotionEvent:

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

Nuevamente, podemos manejar fácilmente los clics en cualquier compuesto compuesto de cualquier TextView:

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

Espero que les haya gustado como a mí. Trataré de mantenerlo actualizado aquí y en una lista relacionada si algo cambia.


Esto funciona para mí :) Que esto te ayude también

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


He creado una simple clase de escucha táctil personalizada en lugar de un EditText personalizado

public class MyTouchListener implements View.OnTouchListener { private EditText editText; public MyTouchListener(EditText editText) { this.editText = editText; setupDrawable(this.editText); } private void setupDrawable(final EditText editText) { editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if(s.length()>0) editText.setCompoundDrawablesWithIntrinsicBounds(0,0, R.drawable.clearicon,0); else editText.setCompoundDrawablesWithIntrinsicBounds(0,0, 0,0); } @Override public void afterTextChanged(Editable s) { } }); } @Override public boolean onTouch(View v, MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_UP) { if(editText.getCompoundDrawables()[2]!=null){ if(event.getX() >= (editText.getRight()- editText.getLeft() - editText.getCompoundDrawables()[2].getBounds().width())) { editText.setText(""); } } } return false; }

}

No se podrá dibujar cuando el EditText esté en blanco. Aparecerá un dibujo cuando comencemos a editar para borrar el EditText.

Simplemente puede configurar el oyente táctil

mEditText.setOnTouchListener (new MyTouchListener (mEditText));


Simplemente copie el siguiente código y haga el truco.

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


Todo es genial, pero ¿por qué no hacerlo realmente simple?

También me he enfrentado a eso no hace mucho ... y el touchlistiner de Android funciona muy bien pero tiene limitaciones de uso ... y llegué a otra solución y espero que eso te ayude:

<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>

Ahora puede crear un escucha o evento ImageClick y hacer lo que quiera con texto. Este archivo edittext_round_corners.xml

<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>


Aquí está mi solución simple, simplemente colocar ImageButtonsobre EditText:

<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>


Es mejor tener ImageButton a la derecha del texto de edición y dar un margen de diseño negativo para que se superponga con el texto de edición. Establecer el oyente en ImageButton y realizar operaciones.


He visto varias soluciones pero ninguna me convenció. Ya sea muy complicado o demasiado simple (no reutilizable).

Este es mi enfoque favorito en este momento:

mEditText.setOnTouchListener( new OnEditTextRightDrawableTouchListener(mEditText) { @Override public void OnDrawableClick() { // The right drawable was clicked. Your action goes here. } });

Y este es el oyente táctil reutilizable:

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

Puedes ver el Gist aquí.


Implementé la respuesta @aristo_sh en Mono.Droid (Xamarin), ya que es un método anónimo de delegado que no puede devolver verdadero o falso, debe tomar e.Event.Handled. También estoy ocultando el teclado al hacer clic.

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



Los elementos dibujables compuestos no se deben poder hacer clic. Es más limpio usar vistas separadas en un LinearLayout horizontal y usar un controlador de clic en ellas.

<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>


Me gustaría sugerir una manera de dibujar a la izquierda! Probé este código y funciona.

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


Para cualquier persona que no quiera implementar el monstruoso manejo de clics. Puedes lograr lo mismo con un RelativeLayout. Con eso incluso tienes manejo libre del posicionamiento del dibujable.

<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>

La ImageViewposición será la misma que usaría, drawableEndy además no necesita toda la gestión de la escucha táctil. Sólo un oyente de clic para el ImageViewy usted es bueno para ir.


Tantas soluciones, pero ninguna funcionó para mí cuando tuve dos campos seguidos. Esta es una solución rápida para agregar un botón de borrado para editar texto, funcionó para mí en mis situaciones donde tengo dos campos o un campo en una fila. Escrito en kotlin!

@SuppressLint("PrivateResource") fun <T : EditText> T.withClear(): T { addTextChangedListener(object : TextWatcher { override fun afterTextChanged(editable: Editable) { setCompoundDrawablesWithIntrinsicBounds(0, 0, if (editable.isNotEmpty()) abc_ic_clear_material else 0, 0) } override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit }) setOnTouchListener { _, event -> if (event.action == ACTION_UP && event.x >= (right - this.compoundPaddingRight)) { setText("") return@setOnTouchListener true } false } return this }


y si el dibujo está a la izquierda, esto te ayudará. (Para los que trabajan con diseño RTL).

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


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


<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>