自定义DrawableTextView——实现TextView左上右下的点击监听

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/salmon_zhang/article/details/75094607

在Android开发中我们经常遇到TextView左上右下有图片的UI布局情形,并且各个图片点击后都要做相应的逻辑操作,这种情况下我们首先想到的是利用线性布局或相对布局去排版,然后给每个图片设置id,再在代码中去获取对应的控件,最后再设置相应的点击事件。这是最常用、最普遍的做法,也比较简单通俗易懂。但是这样写的弊端就是在XML布局文件中代码显得很臃肿,阅读性较差。

最近在做个类似与京东商城的项目,里面有很多类似于这样的布局,由于本人有很强的强迫症,故在网上各种搜索,再加上本人对TextView控件的理解。决定自定义一个UI布局简单,功能更强大的TextView。

大家都知道TextView中有drawableLeft=”“,drawableTop=”“,drawableRight=”“,drawableBottom=”“这四个属性,也就是说我们可以在TextView的左上右下添加图片。那么DrawableTextView的思想就是准确计算出左上右下四张图片在布局中的所占的点击区域,如果点击区域被点击后,则通过接口回调做相应的逻辑操作。好了,直接上代码:

1:自定义DrawableTextView

/**
* Created by salmonzhang on 2017/7/11
* 自定义一个TextView,实现左右点击监听功能
*/
public class DrawableTextView extends android.support.v7.widget.AppCompatTextView {
private DrawableRightClickListener mDrawableRightClickListener;
private DrawableLeftClickListener mDrawableLeftClickListener;
final int DRAWABLE_LEFT = 0;//左图片
final int DRAWABLE_TOP = 1;//上图片
final int DRAWABLE_RIGHT = 2;//右图片
final int DRAWABLE_BOTTOM = 3;//下图片
public DrawableTextView(Context context) {
    this(context,null);
}
public DrawableTextView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs,0);
}
public DrawableTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}
//定义一个右侧监听的接口
public interface DrawableRightClickListener{
    void onDrawableRightClickListener(View view);
}
//定义一个左侧监听的接口
public interface DrawableLeftClickListener{
    void onDrawableLeftClickListener(View view);
}
//定义一个右侧监听的set方法
public void setDrawableRightClickListener(DrawableRightClickListener listener) {
    this.mDrawableRightClickListener = listener;
}
//定义一个左侧监听的set方法
public void setDrawableLeftClickListener(DrawableLeftClickListener listener) {
    this.mDrawableLeftClickListener = listener;
}
//定义一个右侧返回监听的方法
public DrawableRightClickListener getDrawableRightClick() {
    return mDrawableRightClickListener;
}
//定义一个左侧返回监听的方法
public DrawableLeftClickListener getDrawableLeftClick() {
    return mDrawableLeftClickListener;
}

//重写onTouchEvent方法
@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (mDrawableRightClickListener != null) {
                Drawable drawableRight = getCompoundDrawables()[DRAWABLE_RIGHT] ;
                //判断的依据是获取点击区域相对于屏幕的x值大于控件的最右边界减去右侧控件的宽度
                if (drawableRight != null && event.getRawX() >= (getRight() - drawableRight.getBounds().width())) {
                    mDrawableRightClickListener.onDrawableRightClickListener(this);
                    return true ;//返回值一定要是true,否则无法响应
                }
            }
            if (mDrawableLeftClickListener != null) {
                Drawable drawableLeft = getCompoundDrawables()[DRAWABLE_LEFT] ;
                //判断的依据是获取点击区域相对于屏幕的x值小于控件最左边界加上左侧控件的宽度
                if (drawableLeft != null && event.getRawX() <= (getLeft() + drawableLeft.getBounds().width())) {
                    mDrawableLeftClickListener.onDrawableLeftClickListener(this) ;
                    return true ;
                }
            }
            break;
    }
    return super.onTouchEvent(event);
    }
}

2: 在XML使用

<com.example.jdstore.view.DrawableTextView
    android:id="@+id/dtv"
    android:drawableLeft="@mipmap/back"
    android:drawableRight="@mipmap/next"
    android:text="TextView文本"
    />

3:在java代码中使用

    //响应右侧图片的点击事件
    mDtv.setDrawableRightClickListener(new DrawableTextView.DrawableRightClickListener() {
        @Override
        public void onDrawableRightClickListener(View view) {
            //此处执行右侧控件点击后执行的相应逻辑
        }
    });
    //响应左侧图片的点击事件
    mDtv.setDrawableLeftClickListener(new DrawableTextView.DrawableLeftClickListener() {
        @Override
        public void onDrawableLeftClickListener(View view) {
            //此处执行左侧控件点击后执行的相应逻辑
        }
    });

本文就写了左右两侧的监听代码,因为这两种情形是比较常见,也是用的比较多的,大家可以自行借鉴左右两种情形尝试写出上下的监听代码。好了,本文到此为止。如有不足之处,望指教!

猜你喜欢

转载自blog.csdn.net/salmon_zhang/article/details/75094607