I have created a CustomeEditText 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.