自定义EditText实现右侧图标

自定义EditText实现右侧图标

自定义MyEditText继承EditText

package com.pump.yth.mywidget;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
/**
 * Created by yth on 2016/6/16.
 * 重写EditText加入对右侧图标的点击事件
 */
public class MyEditText extends EditText {
    private onDrawableRightListener mRightListener;
    final int DRAWABLE_RIGHT = 2;
    public MyEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    /**
     * 绑定监听事件
     *
     * @param listener onDrawableRightListener
     */
    public void setDrawableRightListener(onDrawableRightListener listener) {
        this.mRightListener = listener;
    }
    /**
     * 监听回调接口
     */
    public interface onDrawableRightListener {
        public void onDrawableRightClick(View view);
    }
//判断点击位置是否是右侧图标,如果是执行相应的回调函数。
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
                if (mRightListener != null) {
                    Drawable drawableRight = getCompoundDrawables()[DRAWABLE_RIGHT];
                    if (drawableRight != null && event.getRawX() >= (getRight() - drawableRight.getBounds().width())) {
                        mRightListener.onDrawableRightClick(this);
                    }
                }
                break;
        }
        return super.onTouchEvent(event);
    }
}

使用:

        //右侧图标点击事件
        mPasswordView.setDrawableRightListener(new MyEditText.onDrawableRightListener() {

            @Override
            public void onDrawableRightClick(View view) {
                //密码可见状态取反
                IS_PASSWORD_SHOW = !IS_PASSWORD_SHOW;
                Drawable drawableright;
                if (IS_PASSWORD_SHOW) {
                    mPasswordView.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
                    drawableright = getResources().getDrawable(R.drawable.ic_password_hidden);
                } else {
                    mPasswordView.setTransformationMethod(PasswordTransformationMethod.getInstance());
                    drawableright = getResources().getDrawable(R.drawable.ic_password_show);
                }
                mPasswordView.setCompoundDrawablesWithIntrinsicBounds(null, null, drawableright, null);
            }
        });

注意:
用到的一些知识点
Android MotionEvent事件
Android View坐标

Android MotionEvent事件响应机制

事件主要包括点击、长按、拖曳、滑动等操作,所有的事件都由如下三个部分作为基础构成:按下(action_down),移动(action_move),抬起(action_up)。
响应归根结底都是基于View以及ViewGroup的,这两者中响应的方法分别有:
View.java

publi boolean dispatchTouchEvent(MotionEvent event)
public boolean onTouchEvent(MotionEvent event)

在ViewGroup.java中

public boolean dispatchTouchEvent(MotionEvent event)
public boolean onTouchEvent(MotionEvent event) 
public boolean onInterceptTouchEvent(MotionEvent event)

MotionEvent对象的理解:

当用户触摸屏幕时将创建一个MotionEvent对象。MotionEvent包含关于发生触摸的位置和时间等细节信息。MotionEvent对象 被传递到程序中合适的 方法比如View对象的onTouchEvent()方法中。在这些方法中我们可以分析MotionEvent对象,以决定要执行的操作。

MotionEvent对象是与用户触摸相关的时间序列,该序列从用户首次触摸屏幕开始,经历手指在屏幕表面的任何移动,直到手指离开屏幕时结束。手指的初次触摸(ACTION_DOWN操作),滑动(ACTION_MOVE操作)和抬起(ACTION_UP)都会创建MotionEvent对象。所以每次触摸时候这三个操作是肯定发生的,而在移动过程中会产生大量事件,每个事件都会产生对应的MotionEvent对象记录发生的操作,触摸的位置,使用的多大压力,触摸的面积,合适发生,以及最初的ACTION_DOWN和时发生等相关的信息。
//----------------------------
dispatchTouchEvent此函数负责事件的分发,当触摸一个View控件,首先会调用这个函数就行,在这个函数体里决定将事件分发给谁来处理。它拥有boolean类型的返回值,当返回为true时,顺序下发会中断。

onTouchEvent 此函数负责执行事件的处理,负责处理事件

onInterceptTouchEvent主要来决定当前控件是否需要拦截传递给子控件,如果返回True表示该控件拦截,并交由自己父类的dispatchTouchEvent处理消费,如果返回false表示不拦截,允许传递给子控件处理。

当Acitivty接收到Touch事件时,将遍历子View进行Down事件的分发。ViewGroup的遍历可以看成是递归的。分发的目的是为了找到真正要处理本次完整触摸事件的View,这个View会在onTouchuEvent结果返回true。
当某个子View返回true时,会中止Down事件的分发,同时在ViewGroup中记录该子View。接下去的Move和Up事件将由该子View直接进行处理。

当ViewGroup中所有子View都不捕获Down事件时,将触发ViewGroup自身的onTouch事件。触发的方式是调用super.dispatchTouchEvent函数,即父类View的dispatchTouchEvent方法。在所有子View都不处理的情况下,触发Acitivity的onTouchEvent方法。

onInterceptTouchEvent有两个作用:1.拦截Down事件的分发。2.中止Up和Move事件向目标View传递,使得目标View所在的ViewGroup捕获Up和Move事件。

//---------------------------------------------------------------------------
整个View的事件转发流程是:
View.dispatchEvent->View.setOnTouchListener->View.onTouchEvent

思路:返回ture事件被消耗,后面的不执行了。

View.dispatchEvent->View.setOnTouchListener(onTouch)->onTouchEvent->onClick。当onTouch返回false时,onTouchEvent才会执行。当onTouchEvent显式调用onClick时(一个完整的触发,down,up),onClick才会执行。

在dispatchTouchEvent中会进行OnTouchListener的判断,如果OnTouchListener不为null且返回true,则表示事件被消费,onTouchEvent不会被执行;否则执行onTouchEvent。


View事件分发

.

参考:
http://www.cnblogs.com/linjzong/p/4191891.html
http://www.2cto.com/kf/201406/308037.html
http://blog.csdn.net/lmj623565791/article/details/38960443
http://www.android100.org/html/201502/26/123262.html 做实验验证一样。

getLeft()getTop()可以得到一个View的位置。这两个方法返回的是相对于其父元素的位置

getRight() =getLeft() + getWidth()
getBottom()= getTop() + getHeight()

//可以在上、下、左、右设置图标,如果不想在某个地方显示,则设置为null。图标的宽高将会设置为固有宽高,既自动通过getIntrinsicWidth和getIntrinsicHeight获取
setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom)
//可以在上、下、左、右设置图标,如果不想在某个地方显示,则设置为null。但是Drawable必须已经setBounds(Rect)
setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom)
//这个方法要先给Drawable设置
setBounds(x,y,width,height);
//设置EdiText的password的隐藏与显示
setTransformationMethod
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容