当前触摸是否在指定范围、某个点:
工具类:
Rect.contains(int x,int y); //返回boolean类型
该函数用于判断某个点是否在当前矩形中,如果在,则返回true,如果不在,则返回false(int X,int Y)就是当前要判断的坐标;
示例:
利用这个函数,可以定义一个简单的控件,绘制一个矩形,当手指在这个矩形区域内点击时,矩形边框是红色,当手指弹起或在边框外点击时,矩形边框为绿色;
public class RectPointView extends View {
private int mX, mY;
private Paint mPaint;
private Rect mrect;
public RectPointView(Context context) {
super(context);
init();
}
public RectPointView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RectPointView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
//初始化参数
mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mrect = new Rect(100, 10, 300, 100);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//触摸事件
mX = (int) event.getX(); //获取到手指所在X的位置
mY = (int) event.getY(); //获取到手指所在的Y位置
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//获取到手指按下,开始重绘控件invalidate()函数必须在主线程,否则会报错
invalidate();
//当返回为true时,表示当前控件已经在拦截这个消息了,如果返回false就表示当前控件不需要这个触摸消息,后续MotionEvent.ACTION_UP类型也不会生效,不主动设置返回true,默认返回为false
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
//获取到手指弹起,开始刷新重画
mX = -1;
mY = -1;
}
//postInvalidate()函数没那么多讲究,可在任意线程
postInvalidate();
return super.onTouchEvent(event);
/**
* 值得注意的是,在MotionEvent.ACTION_DOWN中返回true,因为当MotionEvent.ACTION_DOWN消息到来时,系统会判断返回值,当返回为true时,表示当前控件已经在拦截这个消息了,所以后续的ACTION_MOVE、ACTION_UP消息仍然会继续传递
* 如果返回false(不主动返回true,系统会默认返回false),就表示当前控件不需要这个触摸消息,那么后续的ACTION_MOVE、ACTION_UP消息也就不会再传递;当用户手指弹起时,我们需要还原矩形的颜色(绿色),所以将mX,mY全部设置为负值
* 由于我们构造的Rect矩形坐标并不包含负点,所以也就还原了矩形的绿色;最后调用postInvalidate()函数刷新控件屏幕,让控件重绘postInvalidate()和invalidate()函数都是用来重绘控件的,区别是invalidate()函数一定要在主线程中执行,否则会报错
* 而postInvalidate()函数则没有那么多讲究,可在任意线程中执行,而不一定是主线程,因为在postInvalidate()函数中就是利用handler给主线程发送刷新界面消息来实现的,所以它可以在任何线程中执行都不会报错,而正因为它是通过发送消息来实现的
* 所以它的界面刷新速度可能没有直接调用invalidate()函数那么快,所以在确定当前线程是主线程的时候,还是调用invalidate()函数为主,在不确定当前要刷新界面的线程是不是主线程的时候,还是调用postInvalidate()函数为好
*/
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//Rect、RectF是否包含触摸的坐标
if (mrect.contains(mX, mY)) {
//包含设置画笔为红色
mPaint.setColor(Color.RED);
} else {
//否则为绿色
mPaint.setColor(Color.GREEN);
}
canvas.drawRect(mrect, mPaint);
}
}