在开发APP布局时候经常会看到在EditText的右侧或者左侧出现类似ICON,比如查看密码,点击可以清空输入的字符等,我们通常的做法中在EditText外层再套一层LinearLayout,这无疑增加了布局的复杂度。
今天我们通过扩展EditText来实现四个drawable都可以点击的功能。
实现思路
重写onTouchEvent,当用户点击时,判断点击点是否在图标的位置上,如果在就拦截掉点击事件,调用点击图标的回调
实现步骤
通过
getCompoundDrawables()取得四个方向的drawable取得点击的坐标
把坐标转换到drawable的坐标体系,难点为需要考虑到有多个的情况,所以左右的图标y通过文本垂直中线来计算,上下图标的x同理
分别判断坐标是否包含在图标区域拦截事件
完整实现类
package com.yy.drawableclickedittextdemo;import android.content.Context;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.MotionEvent;public class ClickDrawableEditText extends android.support.v7.widget.AppCompatEditText { private static String tag= ClickDrawableEditText.class.getSimpleName(); //点击位置
private int positionX = 0; private int positionY; // 回调接口
private OnDrawableClickListener onDrawableClickListener; public ClickDrawableEditText(Context context, AttributeSet attrs) { super(context, attrs);
} public ClickDrawableEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr);
} public void setOnDrawableClickListener(OnDrawableClickListener onDrawableClickListener) { this.onDrawableClickListener = onDrawableClickListener;
} @Override
public boolean onTouchEvent(MotionEvent event) { //图标区域
Rect bounds; if (event.getAction() == MotionEvent.ACTION_DOWN) {
positionX = Math.round(event.getX());
positionY = Math.round(event.getY());
Drawable[] ds=this.getCompoundDrawables();
Drawable drawableRight = ds[2];
Drawable drawableLeft = ds[0];
Drawable drawableTop = ds[1];
Drawable drawableBottom = ds[3]; //计算点击点在Drawable中的位置
int xClickPosition,yClickPosition; //长宽
int w=getWidth(); int h=getHeight(); //文本中心的坐标
int midX=(w-getTotalPaddingLeft()-getTotalPaddingRight())/2+getTotalPaddingLeft(); int midY=(h-getTotalPaddingTop()-getTotalPaddingBottom())/2+getTotalPaddingTop(); if (drawableLeft != null) {
bounds = drawableLeft.getBounds(); // 转换到drawableLeft坐标系统
xClickPosition = positionX-getPaddingLeft();
yClickPosition = (midY-positionY)+bounds.height()/2; if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
onDrawableClickListener.onClick(DrawablePosition.LEFT);
event.setAction(MotionEvent.ACTION_CANCEL); return false;
}
} if (drawableRight != null) {
bounds = drawableRight.getBounds();
xClickPosition = positionX - w + bounds.right +getPaddingRight();
yClickPosition= (midY-positionY)+bounds.height()/2; if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
onDrawableClickListener.onClick(DrawablePosition.RIGHT);
event.setAction(MotionEvent.ACTION_CANCEL); return false;
}
} if (drawableTop != null) {
bounds = drawableTop.getBounds();
xClickPosition = (midX - positionX)+bounds.width()/2;
yClickPosition= positionY - getPaddingTop(); if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
onDrawableClickListener.onClick(DrawablePosition.TOP);
event.setAction(MotionEvent.ACTION_CANCEL); return false;
}
} if(drawableBottom!=null)
{
bounds = drawableBottom.getBounds();
xClickPosition = (midX - positionX)+bounds.width()/2;
yClickPosition= positionY - h + bounds.height()+ getPaddingBottom(); if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
onDrawableClickListener.onClick(DrawablePosition.BOTTOM);
event.setAction(MotionEvent.ACTION_CANCEL); return false;
}
}
} return super.onTouchEvent(event);
} /**
* 设置点击图标的侦听接口
*/
public interface OnDrawableClickListener{ public void onClick(int position);
} /**
* 图标的位置方向
*/
public final static class DrawablePosition{ public final static int LEFT=0; public final static int TOP=1; public final static int RIGHT=2; public final static int BOTTOM=3;
}
}引用
在xml布局中引用控件
<com.yy.drawableclickedittext.ClickDrawableEditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/prompt_password" android:padding="0dp" android:drawablePadding="10dp" android:imeActionLabel="@string/action_sign_in_short" android:inputType="textPassword" android:maxLines="1" android:singleLine="true" android:drawableRight="@mipmap/city_icon_care" android:drawableLeft="@mipmap/ic_launcher_round" android:drawableTop="@mipmap/city_icon_care" android:drawableBottom="@mipmap/ic_launcher_round" />
在界面中增加点击侦听
mPasswordView.setOnDrawableClickListener(new ClickDrawableEditText.OnDrawableClickListener() { @Override
public void onClick(int position) {
String str=""; switch (position){ case ClickDrawableEditText.DrawablePosition.LEFT:
str="click left"; break; case ClickDrawableEditText.DrawablePosition.TOP:
str="click top"; break; case ClickDrawableEditText.DrawablePosition.RIGHT:
str="click right"; break; case ClickDrawableEditText.DrawablePosition.BOTTOM:
str="click bottom"; break;
}
Toast.makeText(LoginActivity.this,str,Toast.LENGTH_SHORT).show();
}
});
作者:waiwaaa
链接:https://www.jianshu.com/p/d0458fccfcb5
随时随地看视频