本文是摘抄自 这篇文章,此处作为记录,以备后期查阅使用。在此感谢原文作者的贡献。
使用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());
}