判断自定义异形view的点击事件是否在绘制区域内

本文是摘抄自 这篇文章,此处作为记录,以备后期查阅使用。在此感谢原文作者的贡献。

使用recyclerview显示如下所示的列表,其中item是一个自定义六边形view,点击事件会有重叠情况,所以需要在自定义view中判断,点击事件是否在六边形绘制区域。

PolygonItemView的初始化

    private void initData() {
        //初始化外边框的画笔
        mOuterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mOuterPaint.setStyle(Paint.Style.STROKE);
        mOuterPaint.setStrokeWidth(mOuterWidth);
        mOuterPaint.setColor(mOuterColor);

        //初始化内侧的画笔
        mInnerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mInnerPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mInnerPaint.setColor(mInnerColor);

        //判断点击事件是否在范围内的region
        mRegion = new Region();
        //绘制正六边形的path
        mViewPath = new Path();
    }

在初始化的过程中,主要初始化各类的绘制参数,包括画笔,已经绘制路径的path,和判断其是否在点击区域内的Region。

绘制正六边形

    /**
     * 绘制多边形
     */
    public void lineMultShape(int count) {
        if (count < POLYGON_COUNT) {
            return;
        }
        mViewPath.reset();
        for (int i = 0; i < count; i++) {
            //当前角度
            int angle = 360 / count * i;
            if (i == 0) {
                mViewPath.moveTo(mCenterX + mRadius * MathUtil.cos(angle), mCenterY + mRadius * MathUtil.sin(angle));
            } else {
                mViewPath.lineTo(mCenterX + mRadius * MathUtil.cos(angle), mCenterY + mRadius * MathUtil.sin(angle));
            }
        }
        mViewPath.close();
    }

 

看了这样图,就可以很好的画出正六边形了,将360度分成6分,然后( mCenterX + R*cos α ,mCenterY + R * sinα)就是正六边形的每个端点的坐标,在用Path依次将其连接就可以了。

判断点击区域

其实自定义View,主要解决的是点击区域重合的问题,这里应该在dispatchTouchEvent()中拦截掉事件,然后判断其点击区域是否在正六边形内,来解决点击重合。

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (!isEventInPath(event)) {
                return false;
            }
        }
        return super.dispatchTouchEvent(event);
    }
    /**
     * 判断是否在多边形内
     *
     * @param event
     * @return
     */
    private boolean isEventInPath(MotionEvent event) {
        RectF bounds = new RectF();
        //计算Path的边界
        mViewPath.computeBounds(bounds, true);
        //将边界赋予Region中
        mRegion.setPath(mViewPath, new Region((int) bounds.left, (int) bounds.top,
                (int) bounds.right, (int) bounds.bottom));
        //判断 当前的触摸点是否在这个范围内
        return mRegion.contains((int) event.getX(), (int) event.getY());
    }

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值