Gestion des évènements de clic sur un drawable dans un EditText
j'ai ajouté une image à droite du texte dans un widget EditText
, en utilisant le XML suivant:
<EditText
android:id="@+id/txtsearch"
...
android:layout_gravity="center_vertical"
android:background="@layout/shape"
android:hint="Enter place,city,state"
android:drawableRight="@drawable/cross" />
mais je veux effacer le EditText
quand l'image intégrée est cliquée. Comment puis-je faire cela?
30 réponses
en fait, vous n'avez pas besoin d'étendre une classe. Disons que j'ai un édittext éditcomment avec un 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;
}
});
nous getRawX()
parce que nous voulons obtenir la position réelle de toucher sur l'écran, pas relative à parent.
pour obtenir le clic gauche côté
if(event.getRawX() <= (editComment.getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width()))
très, Très bon, merci à tous ceux qui ont contribué à cette discussion. Donc, si vous ne voulez pas gérer les inconvénients de l'extension de la classe, vous pouvez faire ce qui suit (mis en œuvre pour le droit de tirage seulement)
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;
}
et voici l'implémentation de l'écouteur à nu basée sur la réponse 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);
}
considérez ce qui suit. Ce n'est pas la solution la plus élégante mais ça marche, je viens de le tester.
-
créer une
EditText
classeCustomEditText.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(); } }
-
changez votre mise en page XML pour ceci (où
com.example
est le nom de votre paquet de projet réel):<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" />
-
enfin, ajoutez ceci (ou quelque chose de similaire) à votre activité:
… CustomEditText et = (CustomEditText) this.findViewById(R.id.txtsearch); …
je pourrais être un peu hors avec le calcul des limites de toucher pour le tirable emboîté mais vous obtenez l'idée.
j'espère que cela aidera.
j'ai créé une classe abstraite utile DrawableClickListener qui met en œuvre OnTouchListener .
en plus de la classe DrawableClickListener , j'ai également créé 4 classes abstraites supplémentaires qui étendent la classe DrawableClickListener et gérer le clic de la zone dessinable pour le quadrant correct.
- LeftDrawableClickListener
- TopDrawableClickListener
- RightDrawableClickListener
- BottomDrawableClickListener
Point à considérer
une chose à considérer est que les images ne sont pas redimensionnées si fait de cette façon; ainsi, les images doivent être redimensionnées correctement avant d'être mis dans le res / drawable dossier (s).
Si vous définissez un LinearLayout contenant ImageView et un TextView , il est beaucoup plus facile de manipuler la taille de l'image affichée.
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 "fuzz" 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 "fuzz" 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 "fuzz" 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 "fuzz" 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 "fuzz" 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 "fuzz" 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;
}
}
}
L'utilisation de contains(x,y)
par cette dernière contribution ne fonctionnera pas directement sur le résultat de getBounds()
(sauf, par coïncidence, lors de l'utilisation de tirages" à gauche"). La méthode getBounds
ne fournit que les points de définition Rect
de l'élément étirable normalisé avec l'origine à 0,0 - donc, vous devez en fait faire le calcul du poteau d'origine pour savoir si le clic est dans la zone du tirable dans le contexte des dimensions du texte contenant, mais le changer pour le Haut, Droite, Gauche etc. Vous pouvez aussi décrire un Rect
qui a des coordonnées réellement relatives à sa position dans le EditText
conteneur et utiliser contains()
, bien qu'à la fin vous faites le même calcul.
la combinaison des deux vous donne une solution assez complète, j'ai seulement ajouté un attribut d'instance consumesEvent
qui permet à l'utilisateur de L'API de décider si l'événement de clic doit être transmis ou non en utilisant son résultat pour définir ACTION_CANCEL
ou non.
aussi, je ne vois pas pourquoi les valeurs bounds
et actionX
, actionY
sont des attributs d'instance plutôt que juste des attributs locaux sur la pile.
voici un extrait d'une implémentation basée sur ce qui précède que j'ai assemblé. Il corrige un problème qui pour consommer correctement l'événement que vous devez retourner false. Il ajoute un facteur "fuzz" à. Dans mon cas d'utilisation d'une icône de Contrôle De La Voix dans un champ EditText
, j'ai eu du mal à cliquer, donc le fuzz augmente le limites effectives qui sont considérées comme cliquant sur le drawable. Pour moi 15
a bien fonctionné. J'ai seulement besoin drawableRight
donc je n'ai pas brancher les mathématiques dans les autres, d'économiser de l'espace, mais vous voyez l'idée.
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;
}
}
C'est très simple. Disons que vous avez un drawable sur le côté gauche de votre EditText 'txtsearch'. Les suivants feront l'affaire.
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 vous voulez pour droit tirable modifier l'instruction if en:
if(event.getRawX() >= txtsearch.getRight() - txtsearch.getTotalPaddingRight())
de même, vous pouvez le faire pour tous les tirables composés.
txtsearch.getTotalPaddingTop()
txtsearch.getTotalPaddingBottom()
cet appel de méthode renvoie tout le rembourrage de ce côté, y compris les tirables. Vous pouvez l'utiliser même pour TextView, Button etc.
, Cliquez sur ici pour la référence à partir de l'android developer site.
je pense qu'il est beaucoup plus facile si nous utiliser quelques astuces :)
- créez un bouton image avec votre icône et mettez son arrière-plan couleur à être transparent .
- mettre le bouton image sur L'EditText et de coz le côté droit
- implémenter l'écouteur onclick du bouton pour exécuter votre fonction 151980920"
fait
prolongeant L'idée de RyanM J'ai créé une version plus flexible, qui prend en charge tous les types tirables (Haut, Bas, Gauche, Droite). Alors que le code ci-dessous étend TextView, l'adapter à un texte édité n'est qu'un cas d'échange de "extends TextView" avec "extends EditText". Instantiation le widget de XML est identique à L'exemple de RyanM, sauf le nom du 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;
}}
le DrawableClickListener est aussi simple que ceci:
public interface DrawableClickListener {
public static enum DrawablePosition { TOP, BOTTOM, LEFT, RIGHT };
public void onClick(DrawablePosition target); }
et ensuite la mise en œuvre effective:
class example implements DrawableClickListener {
public void onClick(DrawablePosition target) {
switch (target) {
case LEFT:
doSomethingA();
break;
case RIGHT:
doSomethingB();
break;
case BOTTOM:
doSomethingC();
break;
case TOP:
doSomethingD();
break;
default:
break;
}
}}
p. S.: Si vous ne définissez pas l'écouteur, le fait de toucher à TextView provoquera une NullPointerException. Vous devriez ajouter de la paranoïa au code.
son travail pour moi,
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;
}
});
et si le drawable est à gauche, cela vous aidera. (pour ceux qui travaillent avec la mise en page 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;
}
});
simplement copier coller le code suivant et il fait le tour.
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;
}
});
je sais que c'est assez vieux, mais j'ai récemment dû faire quelque chose de similaire... Après avoir vu à quel point c'est difficile, j'ai trouvé une solution beaucoup plus simple:
- créer une mise en page XML qui contient le texte et L'Image
- sous-classe FrameLayout et gonfler le XML de mise en page
- ajouter le code pour le clic écouteur et tout autre comportement que vous voulez ""
dans mon cas, j'avais besoin D'un texte D'édition qui a la capacité d'effacer le texte avec un bouton. Je voulais qu'il ressemble à SearchView, mais pour un certain nombre de raisons je ne voulais pas utiliser cette classe. L'exemple ci-dessous montre comment j'ai accompli ceci. Même si cela n'a rien à voir avec le changement d'orientation, les principes sont les mêmes et j'ai pensé qu'il serait plus bénéfique d'afficher le code de travail réel que de mettre en place un exemple qui pourrait ne pas fonctionner exactement comme je l'avais prévu:
voici ma mise en page: 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>
et voici la classe qui gonfle cette disposition: 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;
}
}
}
pour rendre cette réponse plus conforme à la question, les mesures suivantes devraient être prises:
- changez la ressource à puiser à tout ce que vous voulez... Dans mon cas, C'était un X gris
- Ajouter un correcteur de mise au point au texte d'édition...
il est préférable d'avoir ImageButton à droite de modifier le texte et de donner une marge de mise en page négative à chevaucher avec modifier le texte. Réglez l'écouteur sur ImageButton et effectuez des opérations.
@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>
pour le clic gauche 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;
}
});
tout est grand mais pourquoi ne pas le rendre vraiment simple?
j'ai rencontré avec aussi pas si longtemps...et Android touchlistiner fonctionne très bien, mais donne une limitation dans l'utilisation..et je suis venu à une autre solution et j'espère que cela vous aidera:
<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>
Vous pouvez maintenant créer ImageClick listener ou event et faire ce que vous voulez avec du texte. This edittext_round_corners.fichier 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>
ne sont pas censés être cliquables. Il est plus propre d'utiliser des vues séparées dans une LinearLayout horizontale et d'utiliser un gestionnaire de clic sur eux.
<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>
pour toute personne qui ne veut pas mettre en œuvre la manipulation de clic monstrueuse. Vous pouvez obtenir la même chose avec un RelativeLayout
. Avec cela, vous avez même la libre manipulation du positionnement du tirable.
<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 position ImageView
sera la même que vous utiliseriez drawableEnd
- en plus, vous n'avez pas besoin de tout le traitement de l'auditeur tactile. Juste un écouteur de clics pour le ImageView
et vous êtes bon pour aller.
cela fonctionne de moi:) que cela vous aide aussi
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;
}
});
voici ma solution simple, il suffit de placer ImageButton
sur 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>
je voudrais suggérer un moyen pour drawable gauche! J'ai essayé ce code et ça marche.
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;
}
});
}
j'ai implémenté la réponse de @aristo_sh En Mono.Droïde (Xamarin), puisque c'est une méthode de délégué anonyme vous ne pouvez pas retourner vrai ou faux vous devez prendre de E. Événement.Gérer. Je cache aussi le clavier sur 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;
}
}
};
partage de ma solution généralisée pour la gestion des évènements de clics et de touches de TextView compound drawable.
tout D'abord, nous avons besoin d'un gestionnaire d'événements tactile:
/**
* 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);
}
Maintenant, vous pouvez traiter tous les événements tactiles sur n'importe quel dessin composé de N'importe quel TextView que vous aimez de cette façon:
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;
}
}
});
Seulement intéressé par les clics? Il suffit de filtrer par action 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);
}
Encore une fois nous pouvons facilement gérer les clics sur n'importe quel dessin composé de N'importe quel 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;
}
}
});
J'espère que vous avez aimé comme moi. Je vais essayer de le garder à jour ici et dans gist lié si quelque chose change.
j'ai créé une classe custom touch listener simple au lieu d'une classe 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;
}
}
il n'y aura pas de tirage lorsque le texte D'édition est vide. Un dessin affichera quand nous avons commencé à éditer pour clarifier le texte édité.
il suffit de définir l'auditeur tactile
mEditText.setOnTouchListener (new MyTouchListener (mEditText));
j'ai vu plusieurs solutions mais aucune ne m'a convaincu. Soit très compliqué, soit trop simple (non réutilisable).
C'est mon approche préférée en ce moment:
mEditText.setOnTouchListener(
new OnEditTextRightDrawableTouchListener(mEditText) {
@Override
public void OnDrawableClick() {
// The right drawable was clicked. Your action goes here.
}
});
Et voici l'auditeur réutilisable touch:
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();
}
suivre le code ci-dessous pour tirer à droite,à gauche,en haut,en bas cliquez:
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;
}
});
}
des Solutions au-dessus du travail, mais ils ont l'effet latéral. Si vous avez un EditText avec droit drawable comme
vous obtiendrez un bouton Coller après chaque clic sur le drawable. Voir Comment désactiver la pâte dans onClickListner pour le Drawable droit d'un EditText android(à l'intérieur de l'icône de EditText) .
tant de solutions, mais aucune ne fonctionnait pour moi quand j'avais deux domaines d'affilée. C'est drop in solution pour ajouter le bouton clair pour éditer le texte, travaillé pour moi dans mes situations où j'ai deux champs ou un champ dans une rangée. Écrit 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
}
final TextView mTvTitle = (TextView)findViewById(R.id.tvTitle1);
mTvTitle.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() <= (mTvTitle.getCompoundDrawables()[DRAWABLE_LEFT].getBounds().width())) {
// your action here
Intent intent = new Intent(DeAddExpences.this,DeHomeActivity.class);
startActivity(intent);
return true;
}
}
return true;
}
});