在开发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