自定義View–支持右側圖片點擊的EditTextView

自定義View–支持右側圖片點擊的EditTextView

知識點:onTouchEvent

在這裏插入圖片描述

相信大家都用過EditTextView的drawableRight屬性,在xml文件中使用android:drawableRight="@mipmap/ic_search",就可以在輸入框的右側增加一個圖標

但是,這個EditTextView並沒有給我們提供這個圖標的點擊回調方法,導致我們無法根據點擊這個圖標來編寫我們之後的邏輯操作。

我們首先需要先能得到這個圖標的位置,再根據我們手指觸摸的屏幕的位置對比是否處在圖標內,就可以繼續我們點擊後的操作了。

所以onTouchEvent()這個回調函數就登場了

首先,我們先了解一下onTouchEvent,onTouchEvent()onTouch() 這兩個方法很像,但是千萬不要弄混了。

  1. onTouchEvent(MotionEvent event)是View中定義的方法,而且是Public類型,所以Activity、ViewGroup、View均可以調用這個方法,最常見的關於這塊的知識點在Android事件分發中,onTouchEvent()是每個事件處理對象都有的方法,用於根據下層的onTouchEvent()返回值類型判斷是否調用,最常見的用法是自定義View時寫入到view中,從而讓該View獲取用戶對手機屏幕的各種操作,並對不同類型的操作實現不同的反饋,屬於一個宏觀的屏幕觸摸監控方法;

  2. onTouch((View v, MotionEvent event)是View.OnTouchListener接口中實現的唯一方法,接收兩個參數,第二個參數是之前提過的event事件對象,第一個參數是一個具體的view類型對象,這就意味着onTouch()方法必須和某個控件進行綁定,即某個控件實現了View.OnTouchListener接口,才能調用onTouch()方法。

首先,我們新建一個class類,名字叫做EditTextWithDrawable(英語不好,隨便起的😹),這個類繼承了AppCompatEditText類,我們需要重寫onTouchEvent這個回調函數。

首先,我們需要先獲取到右側圖標的左右座標閾值,因爲我們是繼承了EditTextView,所以我們可以使用EditTextView提供的函數

  • getWidth() 獲取自定義EditTextView控件的寬度

  • getCompoundPaddingRight()返回視圖的右側填充,以及右側Drawable的空間(如果有)

  • event.getX()手指觸摸的位置座標x

  • getPaddingRight() 返回此視圖的右填充。如果有插入和啓用滾動條,此值可能還包括顯示滾動條所需的空間。

在這裏插入圖片描述

所以,圖片的左閾值爲getWidth() - getCompoundPaddingRight(),右閾值爲getWidth() - getPaddingRight()

我們已經知道了圖片的左右閾值,我們根據觸摸點的x座標與閾值對比,在閾值範圍內即爲點擊到圖片。

注意,我們還需要先獲取圖片資源

EditTextView爲我們提供了方法getCompoundDrawables獲取已設置的drawable

/**
     * Returns drawables for the left, top, right, and bottom borders.
     * 返回值爲左,頂部,右,底部的drawable
     *
     * @attr ref android.R.styleable#TextView_drawableLeft
     * @attr ref android.R.styleable#TextView_drawableTop
     * @attr ref android.R.styleable#TextView_drawableRight
     * @attr ref android.R.styleable#TextView_drawableBottom
     */
    @NonNull
    public Drawable[] getCompoundDrawables() {
        final Drawables dr = mDrawables;
        if (dr != null) {
            return dr.mShowing.clone();
        } else {
            return new Drawable[] { null, null, null, null };
        }
    }

判斷右側圖片是否存在,在進行座標比較。

if (mCompoundRightDrawable != null) {
    if (getWidth() - getCompoundPaddingRight() < event.getX() && getWidth() - getPaddingRight() > event.getX()) {
        if (mRightClickListener != null) {
            mRightClickListener.onClick();
            return true;
        }
    }
}

我們還可以定義一個接口,這樣我們就可以寫回調方法,點擊右側圖片的回調

public interface onDrawableRightClick {
    void onClick();
}

再定義一個public方法,在使用接口回調的地方將listener傳進來

public void setOnRightDrawableClickListener(onDrawableRightClick clickListener) {
    this.mRightClickListener = clickListener;
}

那我們如何使用呢?

首先activity_main.xmll文件添加

<com.felix.baselibrary.UI.EditTextWithDrawable
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:drawableRight="@mipmap/ic_search" />

MainActivity.java

mEtTest = (EditTextWithDrawable) findViewById(R.id.et_test);
mEtTest.setOnRightDrawableClickListener(new EditTextWithDrawable.onDrawableRightClick() {
    @Override
    public void onClick() {
        //這裏我們就可以寫點擊事件了
    }
});

這樣,我們的自定義View就完成了。

本人剛開始寫博客,以前都是通過別人的博客cv代碼,看完就忘了,所以現在打算自己開始寫博客記錄我的學習之旅,寫的不好,大家多多批評

完整源碼

package com.felix.client.widget;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.AppCompatEditText;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

/**
 * Created by fangxin on 2020/4/15.
 */

public class EditTextWithDrawable extends AppCompatEditText {
    private static final String TAG = EditTextWithDrawable.class.getSimpleName();

    private Drawable[] mCompoundDrawables;
    private Drawable mCompoundRightDrawable;
    private Drawable mCompoundLeftDrawable;
    private Drawable mCompoundTopDrawable;
    private Drawable mCompoundBottomDrawable;
    private onDrawableRightClick mRightClickListener;
    private onDrawableLeftClick mLeftClickListener;
    private onDrawableTopClick mTopClickListener;
    private onDrawableBottomClick mBottomClickListener;

    public EditTextWithDrawable(Context context) {
        super(context);
        init();
    }

    public EditTextWithDrawable(Context context, AttributeSet attrs) {
//        super(context, attrs);
        super(context, attrs, android.R.attr.editTextStyle);
        init();
    }

    public EditTextWithDrawable(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mCompoundDrawables = getCompoundDrawables();//getCompoundDrawables() -> Returns drawables for the left, top, right, and bottom borders.
        mCompoundLeftDrawable = mCompoundDrawables[0];
        mCompoundTopDrawable = mCompoundDrawables[1];
        mCompoundRightDrawable = mCompoundDrawables[2];
        mCompoundBottomDrawable = mCompoundDrawables[3];
    }

    public void setOnRightDrawableClickListener(onDrawableRightClick clickListener) {
        this.mRightClickListener = clickListener;
    }

    public void setOnLeftDrawableClickListener(onDrawableLeftClick clickListener) {
        this.mLeftClickListener = clickListener;
    }

    public void setOnTopDrawableClickListener(onDrawableTopClick clickListener) {
        this.mTopClickListener = clickListener;
    }

    public void setOnBottomDrawableClickListener(onDrawableBottomClick clickListener) {
        this.mBottomClickListener = clickListener;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            //右側照片點擊監聽
            if (mCompoundRightDrawable != null) {
                  if (getWidth() - getCompoundPaddingRight() < event.getX() && getWidth() - getPaddingRight() > event.getX()) {
                    if (mRightClickListener != null) {
                        mRightClickListener.onClick();
                        return true;
                    }
                }
            }
            //左側照片點擊
            if (mCompoundLeftDrawable != null) {
                if (getCompoundPaddingLeft() > event.getX() && event.getX() > getPaddingLeft()) {
                    if (mLeftClickListener != null) {
                        mLeftClickListener.onClick();
                        return true;
                    }
                }
            }
            //上側照片點擊
            if (mCompoundTopDrawable != null) {
                if (getCompoundPaddingTop() > event.getY() && event.getY() > getPaddingTop()) {
                    if (mTopClickListener != null) {
                        mTopClickListener.onClick();
                        return true;
                    }
                }
            }
            //下側照片點擊
            if (mCompoundBottomDrawable != null) {
                if (getHeight() - getPaddingBottom() > event.getY() && event.getY() > getHeight() - getCompoundPaddingBottom()) {
                    if (mBottomClickListener != null) {
                        mBottomClickListener.onClick();
                        return true;
                    }
                }
            }
        }
        return super.onTouchEvent(event);
    }

    public interface onDrawableRightClick {
        void onClick();
    }

    public interface onDrawableLeftClick {
        void onClick();
    }

    public interface onDrawableTopClick {
        void onClick();
    }

    public interface onDrawableBottomClick {
        void onClick();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章