web-dev-qa-db-fra.com

Définition de onClickListener pour le droit de dessin d'un EditText

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?

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

    });
96
Hardik4560

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

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.

enter image description here

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

30
MeetM

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