0

I am working in an shopping project and i want to create dynamic end icons in EditText, which changes when user focuses on the EditText.

So basically, before user interacts with the editText, the icon shows Search icon on right side, and when user clicks and enters some info, it shows Clear icon.

I have achieved only gone visible functionality of drawables.

edtSearch.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean b)
            {
                if(b){
                    edtSearch.setCompoundDrawablesWithIntrinsicBounds(0,0,0,0);
                    edtSearch.setCompoundDrawablesWithIntrinsicBounds(0,0,R.drawable.ic_cancel_black_24dp,0);
                }
            }
        });

Oops! How to handle cancel click of search EditText ?

Kdon Patel
  • 99
  • 1
  • 15
Nice umang
  • 1,135
  • 6
  • 19

1 Answers1

1

May be this can help you

public class MyEditText extends EditText {

private Drawable drawableRight;
private Drawable drawableLeft;
private Drawable drawableTop;
private Drawable drawableBottom;

int actionX, actionY;

private DClickListener clickListener;

public MyEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    // this Contructure required when you are using this view in xml
}

public MyEditText(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(DClickListener.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(DClickListener.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(DListener listener) {
    this.clickListener = listener;
}

} 


public interface DClickListener {

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

In you activity you can Add below code where edtSearch is MyEditText object

edtSearch.setDrawableClickListener(new DClickListener() {


    public void onClick(DrawableSide target) {
        switch (target) {
        case LEFT:
            //Do something here
            break;

        default:
            break;
        }
    }

});

Use Xml Like this

  <yourPackageName.MyEditText
        android:id="@+id/imgSearch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
          />
Avinash tiwari
  • 354
  • 1
  • 11