初始化画笔
PathEffect pathEffect = new DashPathEffect(new float[]{10f,10f}, 1);linePaint.setStyle(Paint.Style.STROKE);linePaint.setStrokeWidth(5f);linePaint.setColor(Color.GRAY);linePaint.setPathEffect(pathEffect);
在onDraw方法中使用画笔,画出两条十字虚线
@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawLine(30,getHeight()/2, getWidth()-30,getHeight()/2, linePaint);canvas.drawLine(getWidth()/2, 30, getWidth()/2, getHeight()-30, linePaint);}
画三角形需要用到Path
的相关知识(这部分内容请同学们自行百度),声明及Path
的初始化如下:
Path upTrianglePath = new Path();Path downTrianglePath = new Path();Path leftTrianglePath = new Path();Path rightTrianglePath = new Path();private Path getTrianglePath(int direction) {initTrianglePath();switch (direction) {case 0:// 上return upTrianglePath;case 1: // 下return downTrianglePath;case 2: // 左return leftTrianglePath;case 3: // 右return rightTrianglePath;default:break;}return upTrianglePath;}private void initTrianglePath() {upTrianglePath.moveTo(getWidth()/2, 0);upTrianglePath.lineTo(getWidth()/2 - 30, 52);upTrianglePath.lineTo(getWidth()/2 + 30, 52);upTrianglePath.close();downTrianglePath.moveTo(getWidth()/2, getHeight());downTrianglePath.lineTo(getWidth()/2 - 30, getHeight() - 52);downTrianglePath.lineTo(getWidth()/2 + 30, getHeight() - 52);downTrianglePath.close();leftTrianglePath.moveTo(0, getHeight()/2);leftTrianglePath.lineTo(52, getHeight()/2 + 30);leftTrianglePath.lineTo(52, getHeight()/2 - 30);leftTrianglePath.close();rightTrianglePath.moveTo(getWidth(), getHeight()/2);rightTrianglePath.lineTo(getWidth() - 52, getHeight()/2 + 30);rightTrianglePath.lineTo(getWidth() - 52, getHeight()/2 - 30);rightTrianglePath.close();}
除了使用 Path
之外,因为我们需要画出圆角三角形,所以还需要对 Paint
对象的 PathEffect
做一下设置:
private void initPaint() {
//...trianglePaint.setStyle(Paint.Style.FILL);trianglePaint.setColor(Color.GRAY);float radius = 10f;CornerPathEffect corEffect = new CornerPathEffect(radius);trianglePaint.setPathEffect(corEffect);
//...}
然后在 onDraw
方法中画出四个顶点位置的三角形:
@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//....canvas.drawPath(getTrianglePath(0), trianglePaint);canvas.drawPath(getTrianglePath(1), trianglePaint);canvas.drawPath(getTrianglePath(2), trianglePaint);canvas.drawPath(getTrianglePath(3), trianglePaint);//....}
画圆只需要使用canvas.drawCircle
方法即可,但是由于两个圆一个需要填充内容,一个需要描边,所以我们使用两个Paint
对象来分别实现对应的效果。
声明Paint
对象:
Paint circlePaint1 = new Paint();Paint circlePaint2 = new Paint();private void initPaint() {// ...circlePaint1.setStyle(Paint.Style.FILL);// 填充内容circlePaint1.setColor(Color.GRAY);circlePaint2.setStyle(Paint.Style.STROKE); // 描边circlePaint2.setStrokeWidth(14);circlePaint2.setColor(Color.GRAY);}
然后在 onDraw
方法中画出中心的两个同心圆:
@Overrideprotected void onDraw(Canvas canvas) {// ...canvas.drawCircle(getCircleX(), getCircleY(), 20, circlePaint1);canvas.drawCircle(getCircleX(), getCircleY(), 48, circlePaint2);}
复写onTouchEvent
方法前,需要先设置clickable
为true
,否则我们的View
只能接收到 ACTION_DOWN
事件,无法接收到其他事件。
public SeatAdaptionView(Context context, @Nullable AttributeSet attrs) {
//...setClickable(true);}
然后复写 onTouchEvent
方法,实现同心圆的移动逻辑,实现的思路是:
ACTION_DOWN
时记录初始触摸点ACTION_MOVE
时计算X轴与Y轴的偏移值 deltaX
与 deltaY
,比较二者绝对值大小,根据比较结果设定滑动方向。deltaX
大,则延X轴滑动,deltaY
大则延Y轴滑动。deltaX
(或deltaY
)的值,改变圆心位置,并执行重绘。ACTION_UP
时,恢复到初始状态。 @Overridepublic boolean onTouchEvent(MotionEvent event) {int action = event.getAction();switch(action) {case MotionEvent.ACTION_DOWN:// 1.记录初始触摸点touchX = event.getX();touchY = event.getY();lastX = event.getX();lastY = event.getY();break;case MotionEvent.ACTION_MOVE:// 2.计算X轴与Y轴的偏移值 `deltaX` 与 `deltaY`touchX = event.getX();touchY = event.getY();float deltaX = lastX - touchX;float deltaY = lastY - touchY;if (moveDirection == -1) {// 比较二者绝对值大小,根据比较结果设定滑动方向。`deltaX`大,则延X轴滑动,`deltaY`大则延Y轴滑动。if (Math.abs(deltaX) >= Math.abs(deltaY)) {moveDirection = 0;} else {moveDirection = 1;}} else if (moveDirection == 0) {// 水平方向移动mDeltaX = deltaX;// 3.根据 `deltaX`(或`deltaY`)的值,改变圆心位置,并执行重绘。invalidate();} else {// 垂直方向移动mDeltaY = deltaY;// 根据 `deltaX`(或`deltaY`)的值,改变圆心位置,并执行重绘。invalidate();}break;case MotionEvent.ACTION_UP:// 4.恢复到初始状态。touchX = -1;touchY = -1;moveDirection = -1;mDeltaX = 0;mDeltaY = 0;invalidate();break;default:break;}Log.d("SeatAdaptionView", "onTouchEvent: Action = " + event.getAction() + " touchX = " + touchX + " touchY = " + touchY);return super.onTouchEvent(event);}
代码链接(github)
上一篇:C++动态链接库的使用
下一篇:18-FreeRTOS内核控制