3

I have created a CustomeEditText using this answer in my android application for assigning a drawable click on the right Drawable.

The class is given below.

public class CustomEditText extends EditText {

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

    int actionX, actionY;
    int mHeight = 0;

    private DrawableClickListener clickListener;

        public CustomEditText(Context context) {
        super(context);
    }

    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) {
        mHeight = h;
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    public void setCompoundDrawables(Drawable left, Drawable top,
            Drawable right, Drawable bottom) {
        Log.v("Login", "setCompoundDrawables");
        if (left != null) {
            Log.v("Login", "Left Not Null");
            drawableLeft = left;
        }
        if (right != null) {
            drawableRight = right;
        }
        if (top != null) {
            drawableTop = top;
        }
        if (bottom != null) {
            drawableBottom = bottom;
        }
        Log.v("CustomeEditText", "Left :"+left);
        
        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(DrawableClickListener.DrawablePosition.BOTTOM);
                return super.onTouchEvent(event);
            }

            if (drawableTop != null
                    && drawableTop.getBounds().contains(actionX, actionY)) {
                clickListener.onClick(DrawableClickListener.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;
    }

    public interface DrawableClickListener {

        public static enum DrawablePosition {
            TOP, BOTTOM, LEFT, RIGHT
        };

        public void onClick(DrawablePosition target);
    }

}

So in the xml

<com.mypack.CustomEditText
        android:id="@+id/category"
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:layout_margin="2dp"
        android:background="@drawable/b"
        android:drawablePadding="10dp"
        android:drawableRight="@drawable/category"
        android:hint="My hint"
        android:padding="10dp"
        android:textColor="#000000"
        android:textSize="15sp"
        android:textStyle="bold" />

Now i want to create the same view through code.

I tried to create like this

CustomEditText example = new CustomEditText(this);
    Log.v("Login", "message");
    example.setCompoundDrawables(getResources().getDrawable(R.drawable.delete_category), null, null, null);
    example.setBackgroundResource(R.drawable.category_background);
    example.setGravity(Gravity.CENTER);
    example.setTextColor(getResources().getColor(
            android.R.color.white));
    //example.setMargins(4, 4, 4, 4);
    example.setPadding(4, 4, 4, 4);
    example.setTextSize(20);
    example.setText(category);
    ll.addView(example);

It is creating a normal edittext without drawable on left side.How i can create a CustomeEditText with Drawable on Right Side.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
user965071
  • 1,643
  • 5
  • 16
  • 16
  • I wonder `CustomEditText example = new CustomEditText(this);` code. In you `EditText` class does not have constructor with one parameter – Sieryuu Sep 10 '13 at 09:28
  • I added a Constructor public CustomEditText(Context context) { super(context); } on CustomeEditText. I added now in the Question. – user965071 Sep 10 '13 at 09:29

2 Answers2

1

You should use

example.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.delete_category), null, null, null);

Instead of

example.setCompoundDrawables(getResources().getDrawable(R.drawable.delete_category), null, null, null);

This will result in the your custom EditText with Drawable on left side.

So your code will be like :

CustomEditText example = new CustomEditText(this);
    Log.v("Login", "message");
    example.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.delete_category), null, null, null);
    example.setBackgroundResource(R.drawable.category_background);
    example.setGravity(Gravity.CENTER);
    example.setTextColor(getResources().getColor(
            android.R.color.white));
    //example.setMargins(4, 4, 4, 4);
    example.setPadding(4, 4, 4, 4);
    example.setTextSize(20);
    example.setText(category);
    ll.addView(example);

1. setCompoundDrawable to add Drawables:

If you want to use setCompoundDrawable to add Drawables then you need to specify the bounds using setBounds. That will define a bounding rectangle around the image. If you don't do that, you wont be able to see the Drawable.

eg. In your case use it like,

Drawable img = getResources().getDrawable(R.drawable.delete_category);
img.setBounds( 0, 0, 60, 60 );
example.setCompoundDrawables(img, null, null, null);

2. setCompoundDrawableWithIntrinsicBounds to add Drawables:

You can use setCompoundDrawableWithIntrinsicBounds() instead. It will use the size of the image as the size of the Drawable. ie The Drawables' bounds will be set to their intrinsic bounds.

Ritesh Gune
  • 16,629
  • 6
  • 44
  • 72
-1

android:gravity="right"

put it in your xml or setGravity(Gravity.RIGHT);

gbl
  • 178
  • 2
  • 12
  • 1
    I am able to create a Custom EditText through an xml file. I want the same by code. how this SetGravity will help me on that ? :-( – user965071 Sep 10 '13 at 09:18