項(xiàng)目源碼:https://github.com/lioilwin/StepOrient
利用Android傳感器-方向和計(jì)步組合使用,可以在地圖上記錄人行走的軌跡圖
本文主要是在行走軌跡上增加方向?qū)Ш郊^(類似地圖導(dǎo)航箭頭)
方向箭頭繪制步驟:
1.保存畫布旋轉(zhuǎn)前的狀態(tài)canvas.save()
canvas.translate(mCurX, mCurY); // 平移畫布坐標(biāo)原點(diǎn)
canvas.rotate(orient); // 旋轉(zhuǎn)畫布(相當(dāng)于旋轉(zhuǎn)箭頭)
2.利用mArrowPath會(huì)完成圓弧和三角形組合路徑繪制
3.使用canvas.drawPath(mArrowPath, mPaint)完成填充mArrowPath路徑
4.利用canvas.drawArc(..., mStrokePaint)繪制完整圓環(huán)
5.恢復(fù)畫布旋轉(zhuǎn)前的狀態(tài)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; // 圓點(diǎn)半徑
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對(duì)象
// // 設(shè)置背景透明
// 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();
}
/**
* 當(dāng)屏幕被觸摸時(shí)調(diào)用
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
mCurX = event.getX();
mCurY = event.getY();
addPoint();
return true;
}
/**
* 自動(dòng)增加點(diǎn)
*/
public void autoAddPoint(float stepLen, float endOrient) {
mCurX += (float) (stepLen * Math.sin(Math.toRadians(endOrient)));
mCurY += (float) (stepLen * Math.cos(Math.toRadians(endOrient)));
addPoint();
}
/**
* 增加點(diǎn)
*/
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上畫點(diǎn)
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); // 轉(zhuǎn)動(dòng)畫布
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(); // 恢復(fù)畫布
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);
}
}
簡(jiǎn)書: http://www.reibang.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