? ? ? ?在開發(fā)APP布局時(shí)候經(jīng)常會(huì)看到在EditText的右側(cè)或者左側(cè)出現(xiàn)類似ICON,比如查看密碼,點(diǎn)擊可以清空輸入的字符等,我們通常的做法中在EditText外層再套一層LinearLayout,這無疑增加了布局的復(fù)雜度。
? ? ? ?今天我們通過擴(kuò)展EditText來實(shí)現(xiàn)四個(gè)drawable都可以點(diǎn)擊的功能。
實(shí)現(xiàn)思路
? ? ? ?重寫onTouchEvent,當(dāng)用戶點(diǎn)擊時(shí),判斷點(diǎn)擊點(diǎn)是否在圖標(biāo)的位置上,如果在就攔截掉點(diǎn)擊事件,調(diào)用點(diǎn)擊圖標(biāo)的回調(diào)
實(shí)現(xiàn)步驟
- 通過
getCompoundDrawables()取得四個(gè)方向的drawable - 取得點(diǎn)擊的坐標(biāo)
- 把坐標(biāo)轉(zhuǎn)換到drawable的坐標(biāo)體系,難點(diǎn)為需要考慮到有多個(gè)的情況,所以左右的圖標(biāo)y通過文本垂直中線來計(jì)算,上下圖標(biāo)的x同理
- 分別判斷坐標(biāo)是否包含在圖標(biāo)區(qū)域攔截事件
完整實(shí)現(xiàn)類
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();
//點(diǎn)擊位置
private int positionX = 0;
private int positionY;
// 回調(diào)接口
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) {
//圖標(biāo)區(qū)域
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];
//計(jì)算點(diǎn)擊點(diǎn)在Drawable中的位置
int xClickPosition,yClickPosition;
//長寬
int w=getWidth();
int h=getHeight();
//文本中心的坐標(biāo)
int midX=(w-getTotalPaddingLeft()-getTotalPaddingRight())/2+getTotalPaddingLeft();
int midY=(h-getTotalPaddingTop()-getTotalPaddingBottom())/2+getTotalPaddingTop();
if (drawableLeft != null) {
bounds = drawableLeft.getBounds();
// 轉(zhuǎn)換到drawableLeft坐標(biāo)系統(tǒng)
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);
}
/**
* 設(shè)置點(diǎn)擊圖標(biāo)的偵聽接口
*/
public interface OnDrawableClickListener{
public void onClick(int position);
}
/**
* 圖標(biāo)的位置方向
*/
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"
/>
在界面中增加點(diǎn)擊偵聽
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();
}
});
demo下載
如果需要完整demo,請(qǐng)點(diǎn)擊GitHub下載鏈接