Android-绘图-绘制导航箭头
项目源码:https://github.com/lioilwin/StepOrient
利用Android传感器-方向和计步组合使用,可以在地图上记录人行走的轨迹图
本文主要是在行走轨迹上增加方向导航箭头(类似地图导航箭头)
方向箭头绘制步骤:
1.保存画布旋转前的状态canvas.save()
canvas.translate(mCurX, mCurY); // 平移画布坐标原点
canvas.rotate(orient); // 旋转画布(相当于旋转箭头)
2.利用mArrowPath会完成圆弧和三角形组合路径绘制
3.使用canvas.drawPath(mArrowPath, mPaint)完成填充mArrowPath路径
4.利用canvas.drawArc(…, mStrokePaint)绘制完整圆环
5.恢复画布旋转前的状态canvas.restore();
public class MainSurfaceView extends SurfaceView {
private SurfaceHolder mHolder;
private Bitmap mBitmap;
private Canvas mTmpCanvas;
private Paint mPaint;
private Paint mStrokePaint;
private Path mArrowPath; // 箭头路径
private int cR = 10; // 圆点半径
private int arrowR = 20; // 箭头半径
private float mCurX = 0;
private float mCurY = 0;
private int mPreOrient;
public MainSurfaceView(Context context) {
this(context, null);
}
public MainSurfaceView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MainSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mHolder = getHolder(); // 获得SurfaceHolder对象
// // 设置背景透明
// setZOrderOnTop(true);
// mHolder.setFormat(PixelFormat.TRANSLUCENT);
initPaint(); // 初始化画笔
initArrowPath(); // 初始化箭头路径
}
private void initPaint() {
mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mStrokePaint = new Paint(mPaint);
mStrokePaint.setStyle(Paint.Style.STROKE);
mStrokePaint.setStrokeWidth(5);
}
/**
* 初始化箭头
*/
private void initArrowPath() {
// 初始化箭头路径
mArrowPath = new Path();
mArrowPath.arcTo(new RectF(-arrowR, -arrowR, arrowR, arrowR), 0, -180);
mArrowPath.lineTo(0, -3 * arrowR);
mArrowPath.close();
}
/**
* 当屏幕被触摸时调用
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
mCurX = event.getX();
mCurY = event.getY();
addPoint();
return true;
}
/**
* 自动增加点
*/
public void autoAddPoint(float stepLen, float endOrient) {
mCurX += (float) (stepLen * Math.sin(Math.toRadians(endOrient)));
mCurY += (float) (stepLen * Math.cos(Math.toRadians(endOrient)));
addPoint();
}
/**
* 增加点
*/
private void addPoint() {
if (mTmpCanvas == null) {
mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
mTmpCanvas = new Canvas(mBitmap);
mTmpCanvas.drawColor(Color.GRAY);
}
mTmpCanvas.drawCircle(mCurX, mCurY, cR, mPaint); // 在mBitmap上画点
drawBitmap(0); // 在surfaceView绘图
}
public void autoDrawArrow(int orient) {
if (orient - mPreOrient > 6) {
drawBitmap(orient);
}
mPreOrient = orient;
}
private void drawBitmap(int orient) {
Canvas canvas = mHolder.lockCanvas(); // 加锁,获取canLock
if (canvas == null || mBitmap == null) return;
canvas.drawBitmap(mBitmap, 0, 0, null); // 将mBitmap绘到canLock
canvas.save(); // 保存画布
canvas.translate(mCurX, mCurY); // 平移画布
canvas.rotate(orient); // 转动画布
canvas.drawPath(mArrowPath, mPaint);
canvas.drawArc(new RectF(-arrowR * 0.8f, -arrowR * 0.8f, arrowR * 0.8f, arrowR * 0.8f),
0, 360, false, mStrokePaint);
canvas.restore(); // 恢复画布
mHolder.unlockCanvasAndPost(canvas); // 解锁,把画布显示在屏幕上
}
/**
* 更换背景地图
*/
public void changeBitmap(Bitmap bitmap) {
mBitmap = resizeBitmap(bitmap.copy(Bitmap.Config.ARGB_8888, true), getWidth(), getHeight());
if (mTmpCanvas == null) {
mTmpCanvas = new Canvas();
}
mTmpCanvas.setBitmap(mBitmap);
}
/**
* 缩放bitmap
*/
public static Bitmap resizeBitmap(Bitmap bitmap, float x, float y) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix matrix = new Matrix();
matrix.postScale(x / w, y / h);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, false);
}
}
简书: http://www.jianshu.com/p/824674356f05
CSDN博客: http://blog.csdn.net/qq_32115439/article/details/65946310
GitHub博客:http://lioil.win/2017/03/25/Canvas-Arrow.html
Coding博客:http://c.lioil.win/2017/03/25/Canvas-Arrow.html