美文网首页
自定义EditText实现右侧图标

自定义EditText实现右侧图标

作者: ythmilk | 来源:发表于2016-06-27 22:59 被阅读1463次

    自定义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
    

    相关文章

      网友评论

          本文标题:自定义EditText实现右侧图标

          本文链接:https://www.haomeiwen.com/subject/fjxtjttx.html