继承自View视图控件示例

当前触摸是否在指定范围、某个点:

工具类:

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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值