Android Canvas繪製帶箭頭的直線

先看下效果圖:
在這裏插入圖片描述
下面我們直接看代碼

我自定義了一個View,代碼如下:

package com.davis.drawtrangle;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class DrawView extends View {

    private List<PointBean> pointLists = new ArrayList<PointBean>();

    private PointBean pointBean = new PointBean(-1, -1, -1, -1);

    private static int height = 30;
    private static int bottom = 10;

    private Paint paint = new Paint(){
        {
            setColor(Color.RED);
            setAntiAlias(true);
            setStrokeWidth(4.0f);
        }
    };

    public DrawView(Context context) {
        super(context);
    }

    public DrawView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public DrawView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void clear(){
        if(pointBean != null){
            pointBean.setStartX(-1);
            pointBean.setStartY(-1);
            pointBean.setEndX(-1);
            pointBean.setEndY(-1);
        }

        if(pointLists != null && pointLists.size() > 0){
            pointLists.clear();
        }
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);
        if(pointLists != null && pointLists.size() > 0){
            for(int i=0;i<pointLists.size();i++){
                PointBean pb = pointLists.get(i);
                canvas.drawLine(pb.getStartX(), pb.getStartY(), pb.getEndX(), pb.getEndY(), paint);
                drawTrangle(canvas, paint, pb.getStartX(), pb.getStartY(), pb.getEndX(), pb.getEndY(), height, bottom);
            }
        }

        if(pointBean != null && pointBean.getStartX() != -1
                && pointBean.getStartY() != -1 && pointBean.getEndX() != -1
                && pointBean.getEndY() != -1){
            canvas.drawLine(pointBean.getStartX(), pointBean.getStartY(), pointBean.getEndX(), pointBean.getEndY(), paint);
            drawTrangle(canvas, paint, pointBean.getStartX(), pointBean.getStartY(), pointBean.getEndX(), pointBean.getEndY(), height, bottom);
        }
    }

    /**
     * 繪製三角
     * @param canvas
     * @param fromX
     * @param fromY
     * @param toX
     * @param toY
     * @param height
     * @param bottom
     */
    private void drawTrangle(Canvas canvas, Paint paintLine, float fromX, float fromY, float toX, float toY, int height, int bottom){
        try{
            float juli = (float) Math.sqrt((toX - fromX) * (toX - fromX)
                    + (toY - fromY) * (toY - fromY));// 獲取線段距離
            float juliX = toX - fromX;// 有正負,不要取絕對值
            float juliY = toY - fromY;// 有正負,不要取絕對值
            float dianX = toX - (height / juli * juliX);
            float dianY = toY - (height / juli * juliY);
            float dian2X = fromX + (height / juli * juliX);
            float dian2Y = fromY + (height / juli * juliY);
            //終點的箭頭
            Path path = new Path();
            path.moveTo(toX, toY);// 此點爲三邊形的起點
            path.lineTo(dianX + (bottom / juli * juliY), dianY
                    - (bottom / juli * juliX));
            path.lineTo(dianX - (bottom / juli * juliY), dianY
                    + (bottom / juli * juliX));
            path.close(); // 使這些點構成封閉的三邊形
            canvas.drawPath(path, paintLine);
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action){
            case MotionEvent.ACTION_DOWN:
                onActionDown(event);
                break;
            case MotionEvent.ACTION_MOVE:
                onActionMove(event);
                break;
            case MotionEvent.ACTION_UP:
                onActionUp(event);
                break;
        }
        return true;
        //return super.onTouchEvent(event);
    }

    private void onActionDown(MotionEvent event){
        try {
            if(pointBean == null){
                pointBean = new PointBean(-1, -1, -1, -1);
            }
            pointBean.setStartX(event.getX());
            pointBean.setStartY(event.getY());
        }catch (Exception ex){
            ex.printStackTrace();
        }
        invalidate();
    }

    private void onActionMove(MotionEvent event){
        try{
            if(pointBean != null){
                pointBean.setEndX(event.getX());
                pointBean.setEndY(event.getY());
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
        invalidate();
    }

    private void onActionUp(MotionEvent event){
        try {
            if(pointBean != null){
                pointBean.setEndX(event.getX());
                pointBean.setEndY(event.getY());
                PointBean pb = new PointBean();
                pb.setStartX(pointBean.getStartX());
                pb.setStartY(pointBean.getStartY());
                pb.setEndX(pointBean.getEndX());
                pb.setEndY(pointBean.getEndY());
                pointLists.add(pb);
                pointBean.setStartX(-1);
                pointBean.setStartY(-1);
                pointBean.setEndX(-1);
                pointBean.setEndY(-1);
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
        invalidate();
    }

}

其中關鍵繪製箭頭的是 drawTrangle() 這個方法。

完整的代碼已上傳到github上:Canvas繪製帶箭頭的直線

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章