Android-繪圖-繪制導(dǎo)航箭頭

項(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末膛壹,一起剝皮案震驚了整個(gè)濱河市涡拘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嚼锄,老刑警劉巖减拭,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異灾票,居然都是意外死亡峡谊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門刊苍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)既们,“玉大人,你說(shuō)我怎么就攤上這事正什∩吨剑” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵婴氮,是天一觀的道長(zhǎng)斯棒。 經(jīng)常有香客問(wèn)我,道長(zhǎng)主经,這世上最難降的妖魔是什么荣暮? 我笑而不...
    開(kāi)封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮罩驻,結(jié)果婚禮上穗酥,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好砾跃,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布骏啰。 她就那樣靜靜地躺著,像睡著了一般抽高。 火紅的嫁衣襯著肌膚如雪判耕。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天翘骂,我揣著相機(jī)與錄音壁熄,去河邊找鬼。 笑死碳竟,一個(gè)胖子當(dāng)著我的面吹牛请毛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瞭亮,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼固棚!你這毒婦竟也來(lái)了统翩?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤此洲,失蹤者是張志新(化名)和其女友劉穎厂汗,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體呜师,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娶桦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汁汗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片衷畦。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖知牌,靈堂內(nèi)的尸體忽然破棺而出祈争,到底是詐尸還是另有隱情,我是刑警寧澤角寸,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布菩混,位于F島的核電站,受9級(jí)特大地震影響扁藕,放射性物質(zhì)發(fā)生泄漏沮峡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一亿柑、第九天 我趴在偏房一處隱蔽的房頂上張望邢疙。 院中可真熱鬧,春花似錦、人聲如沸秘症。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)乡摹。三九已至役耕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聪廉,已是汗流浹背瞬痘。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留板熊,地道東北人框全。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像干签,于是被迫代替她去往敵國(guó)和親津辩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容