Android点击画圈并自动连线

场景:对图片进行圈点,并自动连线
使用技术:自定义View绘制,捕捉点击位置的x y坐标,使用canvas进行绘制
效果:

自定义MyCustomPointView代码

public class MyCustomPointView extends View {
    private Context context;
    private List pointRcList=new ArrayList<>();
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    //圆的半径
    private int circleRadius=80;
    //文字大小
    private int textSize=50;
    //是否绘制文字
    private Boolean textWillDraw=Boolean.TRUE;
    /**
     * 是否启用自动画板点击自动连线
     */
    private Boolean willAppendDrawLine=Boolean.FALSE;
    /**
     * 圆圈样式
     */
    private Integer circleColor=Color.GREEN;
    /**
     * 线条样式
     */
    private Integer lineColor=Color.GREEN;

    public MyCustomPointView(Context context) {
        super(context);
        this.context=context;
    }
    /**
     * 获取点的坐标
     * @return
     */
    public List getPointRcList(){
        return pointRcList;
    }
    public MyCustomPointView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context=context;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.i("fplei","widthMeasureSpec="+widthMeasureSpec+",heightMeasureSpec="+heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        Log.i("fplei","changed="+changed+",left="+left+",top="+top+",right="+right+",bottom="+bottom);
    }
    /**
     *  刷新点
     * @param pointRcList
     */
    public void refreshPoint(List pointRcList){
        this.pointRcList.clear();
        this.pointRcList.addAll(pointRcList);
        postInvalidate();
    }

    /**
     * 清除界面
     */
    public void clearAll(){
        this.pointRcList.clear();
        postInvalidate();
    }

    /**
     * 设置是否点击自动追加连线
     * @param value
     */
    public void setWillAppendDrawLine(Boolean value){
        this.willAppendDrawLine=value;
    }

    public void setCircleColor(Integer circleColor) {
        this.circleColor = circleColor;
    }

    public void setLineColor(Integer lineColor) {
        this.lineColor = lineColor;
    }

    public void setCircleRadius(int circleRadius) {
        this.circleRadius = circleRadius;
    }

    /**
     * 添加点
     * @param pointRc
     */
    public void addPointAndRefresh(PointRc pointRc){
        this.pointRcList.add(pointRc);
        postInvalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(5);
        mPaint.setTextSize(textSize);
        for (int i=1;i<=pointRcList.size();i++){
            mPaint.setColor(lineColor);
            PointRc pointRc=pointRcList.get(i-1);
            canvas.drawCircle(pointRc.x, pointRc.y,circleRadius, mPaint);
            if(textWillDraw){
                canvas.drawText(i+"",pointRc.x, pointRc.y,mPaint);
            }
            PointRc nextPointRc=null;
            if( i< pointRcList.size()){
                nextPointRc=pointRcList.get(i);
            }else {
                nextPointRc=pointRcList.get(pointRcList.size()-1);
            }
            mPaint.setColor(circleColor);
            canvas.drawLine(pointRc.x,pointRc.y,nextPointRc.x,nextPointRc.y,mPaint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i("fplei","action="+event.getAction());
        Log.i("fplei","X="+event.getX()+",Y="+event.getY());
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                return true;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_CANCEL:
                // 回收
                break;
            case MotionEvent.ACTION_UP:
                if(willAppendDrawLine){
                    PointRc pointRc=new PointRc();
                    pointRc.x=event.getX();
                    pointRc.y=event.getY();
                    addPointAndRefresh(pointRc);
                }
                break;
        }
        return super.onTouchEvent(event);
    }
}

xml布局使用

< com.uopen.democustomview.MyCustomPointView
        android:id="@+id/MyCustomPointView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

页面使用

@Override
    public void onStart() {
        super.onStart();
        //初始化数据
        List pointRcList=new ArrayList<>();
        pointRcList.add(new PointRc(450,100));
        pointRcList.add(new PointRc(480,350));
        pointRcList.add(new PointRc(330,500));
        pointRcList.add(new PointRc(510,650));
        pointRcList.add(new PointRc(780,800));
        pointRcList.add(new PointRc(450,900));
        pointRcList.add(new PointRc(450,1200));
        pointRcList.add(new PointRc(550,1400));
        //设置是否点击自动追加连线
        binding.MyCustomPointView.setWillAppendDrawLine(Boolean.TRUE);
        binding.MyCustomPointView.setCircleColor(Color.GREEN);
        binding.MyCustomPointView.setLineColor(Color.RED);
        //设置圆圈大小
        binding.MyCustomPointView.setCircleRadius(80);
        binding.MyCustomPointView.refreshPoint(pointRcList);
    }

拓展
1.可以完善返回上一步操作
2.可以选择某个点进行删除,并自动重新连线
3.绘制圆圈时可以加上一些动效