Preface
In the input box EditText, we often add icons such as deleting X, drop-down arrows to get better user experience and needs. If on the right side, we often set the drawableRight attribute to achieve, then how do these icons respond to click events? Here's a brief record!
Method
First of all, we need to inherit AppCompat EditText and implement a custom EditText. (Now, in order to be compatible with and implement MD style, we will inherit AppCompat EditText instead of EditText. In addition, AS will give the corresponding error warning!)
Then, with the help of onTouchEvent, it responds to the click event of the icon according to the touch position, and judges whether the x and y coordinates of the finger are clicked on the drawable object. These parameters need to be clarified:
event.getRawX()//Relative to the absolute coordinates of the left boundary, the upper left corner is (0,0)
event.getX()//Relative to its own coordinates, the upper left corner of the space is (0,0)
getLeft()//Equivalent to margin, the distance between the left boundary of the control and its parent
getPaddingLeft()//Equivalent to padding, the distance between elements in a control and the control
getBounds().width()//Gets the width of the element drawing area
drawableRight.getIntrinsicWidth()//Get the actual width of drawable
Then you need to get this icon. Here you can get a drawable array of length 4 by calling getCompound Drawables (), and store drawableLeft, Right, Top, Bottom four image resource objects:
final int DRAWABLE_LEFT = 0;
final int DRAWABLE_TOP = 1;
final int DRAWABLE_RIGHT = 2;
final int DRAWABLE_BOTTOM = 3;
According to the location of the icon, you can get the corresponding picture Drawable.
Finally, by declaring an interface and defining a callback method, I will not go into details here, which is more common!
Specific realization
public class DropDownEditText extends AppCompatEditText {
final int DRAWABLE_LEFT = 0;
final int DRAWABLE_TOP = 1;
final int DRAWABLE_RIGHT = 2;
final int DRAWABLE_BOTTOM = 3;
public DropDownEditText(Context context) {
super(context);
}
public DropDownEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public interface OnDropArrowClickListener {
void onDropArrowClick();
}
private OnDropArrowClickListener onDropArrowClickListener;
public void setOnDropArrowClickListener(OnDropArrowClickListener onDropArrowClickListener) {
this.onDropArrowClickListener = onDropArrowClickListener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
Drawable drawableRight = getCompoundDrawables()[DRAWABLE_RIGHT];
if (drawableRight != null) {
//The x-axis coordinates of this click event, if > current control width - control right spacing - drawable actual display size
if (event.getX() >= (getWidth() - getPaddingRight() - drawableRight.getIntrinsicWidth())) {
//Set up to click the EditText icon on the right to lose focus.
// Prevent clicking EditText icon on the right side of EditText to get focus and pop-up the soft keyboard
setFocusableInTouchMode(false);
setFocusable(false);
if (onDropArrowClickListener != null) {
onDropArrowClickListener.onDropArrowClick();
}
} else {
setFocusableInTouchMode(true);
setFocusable(true);
}
}
}
return super.onTouchEvent(event);
}
}
The example shows the icon on the right, in the same other position:
Right:
//Another direct approach
//Actually, it's the left-most drawable.xcoordinate,drawableRight.getIntrinsicWidth()==drawableRight.getBounds().width()Equal to the width of the icon
event.getRawX() >= (getRight() - drawableRight.getBounds().width())
On the left:
/**getX Relative to the x coordinate of the upper left corner of the control itself, <== the left margin of the control + the actual width of the image object. This getLeft is equivalent to margin, and getPadding Left is equivalent to padding.*/
event.getX() <= getLeft() + drawableLeft.getIntrinsicWidth()
event.getRawX() <= (getLeft() + drawableLeft.getBounds().width())
Above:
event.getY() <= getTop() + drawableTop.getIntrinsicHeight()
Below:
event.getX() > getHeight() - drawableBottom.getIntrinsicWidth()
call
Get the instance directly and call the method.
editText = (DropDownEditText) findViewById(R.id.xxxxx);
editText.setOnDropArrowClickListener(new DropDownEditText.OnDropArrowClickListener() {
@Override
public void onDropArrowClick() {
//xxxxxxxx
}
});
problem
When you click, you get the focus and pop up the soft keyboard. Here's a solution:
Android implements EditText to respond to drawable right click events
That is, if you click on the icon on the right, it will lose focus:
setFocusableInTouchMode(false);
setFocusable(false);
This method, although it can avoid pop-up input method, but EditText below the line, or will light up, the experience is not very good, if you know, you can guide, thank you!
Reference article:
EditText sets DrawableRight, DrawableLeft, DrawableTop... Click Events