दिलचस्प पोस्ट
वस्तु गुणों की तुलना सी # में एंड्रॉइड में स्क्रॉलएव्यू लंबवत और क्षैतिज पॉलिमर 1.0 में सरणियों के बजाय वस्तुओं के साथ डोम-दोहराने का उपयोग कैसे करें? कंट्रोलर डिवी में कर्सर की स्थिति कैसे प्राप्त करें? माउस पॉइंटर को एक विशिष्ट स्थिति में ले जाएं? कैसे PHP के साथ एक foreach लूप में लाइनों पंगा लेना प्रत्येक नियंत्रक / क्रिया विधि से सत्र स्थिति सक्षम / अक्षम करें LINQ रिकर्सन फ़ंक्शन? पायथन में डिक्ट्स के एक अक्षर को प्रारंभ करने का सबसे अच्छा तरीका क्या है? सिंगेट्टन: अच्छा डिजाइन या एक बैसाखी? सेज फ़ाइलों का नाम बदलने के लिए सेज का उपयोग करना JQuery का उपयोग कर एक div का भीतरी एचटीएमएल कैसे बदल सकता है? एसक्यूएल: पंक्तियों का चयन जहां स्तंभ मान को पिछले पंक्ति से बदल दिया गया था जेएसन के लिए एमवीसी 4 विधानसभा संदर्भ लापता। एन्कोड यादृच्छिक रंग जनरेटर

एक संपादन टेक्स्ट के भीतर एक ड्रॉएबल पर क्लिक ईवेंट को संभालना

मैंने निम्नलिखित 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 साफ़ करना चाहता हूं। मैं यह कैसे कर सकता हूँ?

Solutions Collecting From Web of "एक संपादन टेक्स्ट के भीतर एक ड्रॉएबल पर क्लिक ईवेंट को संभालना"

वास्तव में आपको किसी भी कक्षा को बढ़ाने की आवश्यकता नहीं है। मान लीजिए कि मेरे पास एक संपादन टेस्ट संपादन है जिसमें ड्रॉएबल राइट है

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

हमें getRawX() मिलता है क्योंकि हम स्क्रीन पर वास्तविक स्थिति को स्पर्श करना चाहते हैं, माता-पिता के सापेक्ष नहीं।

बाईं ओर क्लिक करने के लिए क्लिक करें

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

बहुत, बहुत अच्छा, इस चर्चा में योगदान देने वाले सभी के लिए धन्यवाद इसलिए यदि आप कक्षा को बढ़ाने के असुविधा से निपटना नहीं चाहते हैं, तो आप निम्न कर सकते हैं (केवल सही ड्रॉएबल के लिए लागू)

 this.keyword = (AutoCompleteTextView) findViewById(R.id.search); this.keyword.setOnTouchListener(new RightDrawableOnTouchListener(keyword) { @Override public boolean onDrawableTouch(final MotionEvent event) { return onClickSearch(keyword); } }); private boolean onClickSearch(final View view) { // 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); } 

निम्नलिखित को धयान मे रखते हुए। यह सबसे सुरुचिपूर्ण समाधान नहीं है, लेकिन यह काम करता है, मैंने अभी परीक्षण किया है।

  1. एक कस्टमाइज़ किया गया CustomEditText.java क्लास बनाएँ 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. अपने लेआउट XML को इस पर बदलें (जहां com.example आपका वास्तविक पैकेज पैकेज है):

     <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. अंत में, अपनी गतिविधि में यह (या कुछ इसी तरह) जोड़ें:

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

मैं नेस्टेड ड्रॉएबल के लिए स्पर्श सीमा की गणना के साथ थोड़ा सा हो सकता है लेकिन आपको यह विचार मिलता है।

आशा है कि ये आपकी मदद करेगा।

उस अंतिम अंशदान के उपयोग में contains(x,y) सीधे प्राप्त होने के परिणाम पर काम नहीं करेंगे getBounds() , इसके अलावा, संयोग से, "बाएं" getBounds() का उपयोग करते समय) getBounds विधि केवल 0,0 पर उत्पत्ति के साथ सामान्यीकृत getBounds आइटम के अंक को परिभाषित करता है – इसलिए, वास्तव में यह जानने के लिए मूल क्लिक के गणित को करने की आवश्यकता है कि क्या क्लिक संदर्भ में ड्रॉएबल के क्षेत्र में है संपादित करेंटेक्स्ट के आयामों में से है, लेकिन इसे शीर्ष, दाएं, बायां आदि के लिए बदल सकते हैं। वैकल्पिक रूप से आप एक Rect वर्णन कर सकते हैं जो वास्तव में EditText कंटेनर में अपनी स्थिति के सापेक्ष समन्वय करता है और उपयोग contains() , हालांकि अंत में आप कर रहे हैं वही गणित

उन दोनों का मेल आपको एक बहुत ही पूर्ण समाधान प्रदान करता है, मैंने केवल एक उदाहरण विशेषता consumesEvent जो कि एपीआई उपयोगकर्ता को यह तय करने देता है कि क्या क्लिक ईवेंट को उसके परिणामों को ACTION_CANCEL सेट करने के लिए या नहीं पर पारित किया जाना चाहिए या नहीं

इसके अलावा, मैं नहीं देख सकता कि bounds और actionX , actionY वैल्यू actionY पर स्थानीय के बजाय उदाहरण क्यों है।

यहाँ पर आधारित एक कार्यान्वयन से एक कटआउट है जो मैंने एक साथ रखा था। यह एक समस्या को हल करता है जो ठीक से उस घटना का उपभोग करता है जिसे आपको झूठी वापसी की आवश्यकता है। यह एक "फज़" फैक्टर को जोड़ता है एक 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; } } 

मैंने एक उपयोगी सार वर्ग DrawableClickListener बनाया है जो OnTouchListener को लागू करता है

DrawableClickListener वर्ग के अतिरिक्त, मैंने 4 अतिरिक्त सार वर्ग भी बनाए जो DrawableClickListener वर्ग का विस्तार करते हैं और सही चतुर्भुज के लिए ड्रॉएबल क्षेत्र के क्लिक को संभालना

  • LeftDrawableClickListener
  • TopDrawableClickListener
  • RightDrawableClickListener
  • BottomDrawableClickListener

बिंदु पर विचार करने के लिए

एक बात पर विचार करना है कि यदि इस तरीके से छवियों का पुन: आकार नहीं किया गया है; इस प्रकार छवियों को सही / रेखांकित फ़ोल्डर (एस) में डालने से पहले ठीक से स्केल किया जाना चाहिए

यदि आप एक LinearLayout में एक छवि दृश्य और एक TextView को परिभाषित करते हैं, तो प्रदर्शित होने वाली छवि के आकार में हेरफेर करना बहुत आसान है।


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

यह बहुत सरल है। चलिए कहते हैं कि आपके पास एड्यूट टेक्स्ट 'टीएक्सट्सचर्च' के बाईं तरफ एक ड्रॉ योग्य है निम्नलिखित चाल करेंगे

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

इस पद्धति से कॉल किसी भी डैबिलल सहित उस तरफ सभी पैडिंग लौटाता है। आप इसे भी TextView, बटन आदि के लिए उपयोग कर सकते हैं।

एंड्रॉइड डेवलपर साइट से संदर्भ के लिए यहां क्लिक करें ।

मुझे लगता है कि अगर हम कुछ चाल का उपयोग करते हैं तो यह बहुत आसान है 🙂

  1. अपने आइकन के साथ एक छवि बटन बनाएं और पारदर्शी होने के लिए उसका पृष्ठभूमि रंग सेट करें।
  2. संपादन टेक्स्ट पर छवि बटन डालें और दाएं हाथ की तरफ coz करें
  3. अपने फ़ंक्शन को निष्पादित करने के लिए बटन के ऑनक्लिक श्रोता को लागू करें

किया हुआ

रयान एमए द्वारा विचार को बढ़ाते हुए मैंने एक अधिक लचीला संस्करण बनाया है, जो सभी चित्रकारी प्रकारों (ऊपर, नीचे, बाएं, दाएं) का समर्थन करता है। नीचे दिए गए कोड में TextView को विस्तारित करते हुए, इसे एक EditText के लिए आदत डालते हुए "TextView बढ़ाता है" के साथ "EditText विस्तारित" के साथ ही गमागमन का मामला है Instantiation XML से विजेट RyanM के उदाहरण के समान है, विजेट नाम को बार करें।


 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 इस रूप में सरल है:

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

ps: यदि आप श्रोता सेट नहीं करते हैं, तो TextView को स्पर्श करने से एक NullPointerException होगा। आप कोड में कुछ और पागलपन जोड़ना चाह सकते हैं।

इसके लिए मेरे काम,

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

मुझे पता है यह काफी पुराना है, लेकिन मुझे हाल ही में ऐसा कुछ करना था … यह देखने के बाद कि यह कितना मुश्किल है, मैं एक बहुत ही सरल समाधान के साथ आया था:

  1. एक XML लेआउट बनाएं जिसमें संपादन टेक्स्ट और छवि शामिल है
  2. उपवर्ग फ़्रेम लेआउट और एक्सएमएल लेआउट बढ़ाना
  3. क्लिक श्रोता और आप चाहते हैं कि किसी अन्य व्यवहार के लिए कोड जोड़ें

मेरे मामले में, मुझे एक संपादन टेक्स्ट की जरूरत थी, जिसमें एक बटन के साथ पाठ को साफ़ करने की क्षमता थी। मैं इसे SearchView की तरह दिखना चाहता था, लेकिन कई कारणों से मैं उस वर्ग का उपयोग नहीं करना चाहता था। नीचे दिए गए उदाहरण से पता चलता है कि मैंने यह कैसे पूरा किया। यद्यपि फोकस परिवर्तन के साथ ऐसा करने की ज़रूरत नहीं है, सिद्धांत समान हैं और मैंने सोचा था कि वास्तविक उदाहरण काम करने के बजाय वास्तविक कार्य कोड पोस्ट करने के लिए इससे अधिक फायदेमंद होगा जो संभवत: मेरा उद्देश्य नहीं है:

यहाँ मेरा लेआउट है: 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> 

और यहां वह कक्षा है जो उस लेआउट को फुला देती है: साफ़ करने योग्य EditText.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; } } } 

यह उत्तर अधिक प्रश्न बनाने के लिए निम्नलिखित कदम उठाए जाने चाहिए:

  1. जो कुछ भी आप चाहते हैं उसके लिए ड्रॉएबल संसाधन बदलें … मेरे मामले में यह एक ग्रे एक्स था
  2. संपादन पाठ को फ़ोकस बदलें श्रोता जोड़ें …

संपादित करने के अधिकार के लिए ImageButton को बेहतर करना और संपादन टेक्स्ट के साथ ओवरलैप करने के लिए नकारात्मक लेआउट मार्जिन देना बेहतर होगा। Set listener on ImageButton and perform operations.

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

for left drawable click listener

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

Compound drawables are not supposed to be clickable. It is cleaner to use separate views in a horizontal LinearLayout and use a click handler on them.

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

Simply copy paste the following code and it does the trick.

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

Here's my simple solution, just place ImageButton over 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> 

It is all great but why not to make it really simple?

I have faced with that also not so long ago…and android touchlistiner works great but gives limitation in usage..and I came to another solution and I hope that will help you:

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

यहां छवि विवरण दर्ज करें Now you can create ImageClick listener or event and do what ever you want with text. This edittext_round_corners.xml file

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

I would like to suggest a way for drawable left! I tried this code and works.

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

I implemented @aristo_sh answer in Mono.Droid (Xamarin), since it's a delegate anonymous method you can't return true or false you have to take take of e.Event.Handled. I am also hiding the keyboard on click

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

Sharing my generalized solution for handling TextView compound drawable click and touch events.

First we need a touch event handler:

 /** * 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 - ie within {@code drawableBounds}. * If using fuzz, may return negative coordinates. */ protected abstract boolean onDrawableTouch(View v, int drawableIndex, Rect drawableBounds, MotionEvent event); } 

Now you can process any touch events on any compound drawable of any TextView you like this way:

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

Only interested in clicks? Just filter out by MotionEvent action:

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

Again we can easily handle clicks on any compound drawable of any 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; } } }); 

Hope you liked it as I did. I will try to keep it updated here and in related gist if anything changes.

I have created a simple custom touch listener class instead of a custom EditText

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

}

There will be no drawable when the EditText is blank. A drawable will show when we started editing for clear the EditText.

You can just set the touch listener

mEditText.setOnTouchListener(new MyTouchListener(mEditText));

For anyone who does not want to implement the monstrous click handling. You can achieve the same with a RelativeLayout . With that you even have free handling of the positioning of the drawable.

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

The ImageView position will be the same as you would use drawableEnd – plus you don't need all the touch listener handling. Just a click listener for the ImageView and you are good to go.

This works fro me:) may this help you as well

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