Dans mon application, j'ai un EditText
avec une icône de recherche sur le côté droit. J'ai utilisé le code donné ci-dessous.
<EditText
Android:id="@+id/search"
Android:layout_width="0dp"
Android:layout_height="match_parent"
Android:layout_margin="4dip"
Android:layout_weight="1"
Android:background="@drawable/textfield_search1"
Android:drawableLeft="@drawable/logo"
Android:drawableRight="@drawable/search_icon"
Android:hint="Search Anything..."
Android:padding="4dip"
Android:singleLine="true" />
Je veux définir le onClickListener
pour l'image d'icône de recherche assignée à droite du dessin de EditText
. Comment est-ce possible?
public class CustomEditText extends EditText {
private Drawable drawableRight;
private Drawable drawableLeft;
private Drawable drawableTop;
private Drawable drawableBottom;
int actionX, actionY;
private DrawableClickListener clickListener;
public CustomEditText (Context context, AttributeSet attrs) {
super(context, attrs);
// this Contructure required when you are using this view in xml
}
public CustomEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
public void setCompoundDrawables(Drawable left, Drawable top,
Drawable right, Drawable bottom) {
if (left != null) {
drawableLeft = left;
}
if (right != null) {
drawableRight = right;
}
if (top != null) {
drawableTop = top;
}
if (bottom != null) {
drawableBottom = bottom;
}
super.setCompoundDrawables(left, top, right, bottom);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Rect bounds;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
actionX = (int) event.getX();
actionY = (int) event.getY();
if (drawableBottom != null
&& drawableBottom.getBounds().contains(actionX, actionY)) {
clickListener.onClick(DrawablePosition.BOTTOM);
return super.onTouchEvent(event);
}
if (drawableTop != null
&& drawableTop.getBounds().contains(actionX, actionY)) {
clickListener.onClick(DrawablePosition.TOP);
return super.onTouchEvent(event);
}
// this works for left since container shares 0,0 Origin with bounds
if (drawableLeft != null) {
bounds = null;
bounds = drawableLeft.getBounds();
int x, y;
int extraTapArea = (int) (13 * getResources().getDisplayMetrics().density + 0.5);
x = actionX;
y = actionY;
if (!bounds.contains(actionX, actionY)) {
/** Gives the +20 area for tapping. */
x = (int) (actionX - extraTapArea);
y = (int) (actionY - extraTapArea);
if (x <= 0)
x = actionX;
if (y <= 0)
y = actionY;
/** Creates square from the smallest value */
if (x < y) {
y = x;
}
}
if (bounds.contains(x, y) && clickListener != null) {
clickListener
.onClick(DrawableClickListener.DrawablePosition.LEFT);
event.setAction(MotionEvent.ACTION_CANCEL);
return false;
}
}
if (drawableRight != null) {
bounds = null;
bounds = drawableRight.getBounds();
int x, y;
int extraTapArea = 13;
/**
* IF USER CLICKS JUST OUT SIDE THE RECTANGLE OF THE DRAWABLE
* THAN ADD X AND SUBTRACT THE Y WITH SOME VALUE SO THAT AFTER
* CALCULATING X AND Y CO-ORDINATE LIES INTO THE DRAWBABLE
* BOUND. - this process help to increase the tappable area of
* the rectangle.
*/
x = (int) (actionX + extraTapArea);
y = (int) (actionY - extraTapArea);
/**Since this is right drawable subtract the value of x from the width
* of view. so that width - tappedarea will result in x co-ordinate in drawable bound.
*/
x = getWidth() - x;
/*x can be negative if user taps at x co-ordinate just near the width.
* e.g views width = 300 and user taps 290. Then as per previous calculation
* 290 + 13 = 303. So subtract X from getWidth() will result in negative value.
* So to avoid this add the value previous added when x goes negative.
*/
if(x <= 0){
x += extraTapArea;
}
/* If result after calculating for extra tappable area is negative.
* assign the original value so that after subtracting
* extratapping area value doesn't go into negative value.
*/
if (y <= 0)
y = actionY;
/**If drawble bounds contains the x and y points then move ahead.*/
if (bounds.contains(x, y) && clickListener != null) {
clickListener
.onClick(DrawableClickListener.DrawablePosition.RIGHT);
event.setAction(MotionEvent.ACTION_CANCEL);
return false;
}
return super.onTouchEvent(event);
}
}
return super.onTouchEvent(event);
}
@Override
protected void finalize() throws Throwable {
drawableRight = null;
drawableBottom = null;
drawableLeft = null;
drawableTop = null;
super.finalize();
}
public void setDrawableClickListener(DrawableClickListener listener) {
this.clickListener = listener;
}
}
Créez également une interface avec
public interface DrawableClickListener {
public static enum DrawablePosition { TOP, BOTTOM, LEFT, RIGHT };
public void onClick(DrawablePosition target);
}
Toujours si tu as besoin d’aide, commente
Définissez également drawableClickListener sur la vue du fichier d'activité.
editText.setDrawableClickListener(new DrawableClickListener() {
public void onClick(DrawablePosition target) {
switch (target) {
case LEFT:
//Do something here
break;
default:
break;
}
}
});
Solution simple, utilisez des méthodes que Android a déjà données, plutôt que de réinventer wheeeeeeeeeel: -)
editComment.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
final int DRAWABLE_LEFT = 0;
final int DRAWABLE_TOP = 1;
final int DRAWABLE_RIGHT = 2;
final int DRAWABLE_BOTTOM = 3;
if(event.getAction() == MotionEvent.ACTION_UP) {
if(event.getRawX() >= (editComment.getRight() - editComment.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
// your action here
return true;
}
}
return false;
}
});
Cela a déjà été répondu, mais j'ai essayé une méthode différente pour simplifier les choses.
L’idée est de placer un ImageButton
à droite de EditText
et d’avoir une marge négative, de sorte que le EditText
se jette dans le ImageButton
en le faisant ressembler le bouton est dans le EditText
.
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal">
<EditText
Android:id="@+id/editText"
Android:layout_weight="1"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:hint="Enter Pin"
Android:singleLine="true"
Android:textSize="25sp"
Android:paddingRight="60dp"
/>
<ImageButton
Android:id="@+id/pastePin"
Android:layout_marginLeft="-60dp"
style="?android:buttonBarButtonStyle"
Android:paddingBottom="5dp"
Android:src="@drawable/ic_action_paste"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
</LinearLayout>
En outre, comme indiqué ci-dessus, vous pouvez utiliser un paddingRight
de largeur similaire dans le EditText
si vous ne voulez pas que son texte soit survolé par le ImageButton
.
J'ai deviné la taille de la marge avec l'aide du concepteur de la mise en page d'Android-studio et elle a l'air similaire quelle que soit la taille de l'écran. Sinon, vous pouvez calculer la largeur de ImageButton
et définir la marge par programmation.
Autant que je sache, vous n’avez pas accès à la bonne image, à moins que vous ne remplaciez l’événement onTouch
. Je suggère d'utiliser un RelativeLayout
, avec un editText
et un imageView
, et de placer OnClickListener
sur la vue de l'image comme ci-dessous:
<RelativeLayout
Android:id="@+id/rlSearch"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:background="@Android:drawable/edit_text"
Android:padding="5dip" >
<EditText
Android:id="@+id/txtSearch"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_centerVertical="true"
Android:layout_toLeftOf="@+id/imgSearch"
Android:background="#00000000"
Android:ems="10"/>
<ImageView
Android:id="@+id/imgSearch"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentRight="true"
Android:layout_centerVertical="true"
Android:src="@drawable/btnsearch" />
</RelativeLayout>