多个可以拖动的小球与一个用户连接,利用最远用户作为可变圆的半径,一个类似圆盘的效果。

先来看效果(效果不全,所有的点都可以动,圆的半径也可以变化)

直接来代码吧 (图片资源自己添加)复制即可看到效果

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;

public class MyView extends View {

    private int width;
    private int height;

    private ArrayList<int[]> list;
    private Bitmap[] bitmaps;
    private ArrayList<Integer> delyList;


    //绘制背景图片
    private Bitmap bitmap;
    private Bitmap pic1;
    private Bitmap pic2;
    private Bitmap pic3;
    private Bitmap pic4;
    private Bitmap pic5;
    private Bitmap pic6;
    private Bitmap pic7;


    public MyView(Context context) {
        super(context);
        init();
    }

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

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

        init();
    }

    private void init() {
        //绘制背景图片
        bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.car_topview_full);

        bitmaps = new Bitmap[]{
                pic1 = BitmapFactory.decodeResource(getResources(), R.mipmap.pople),
                pic2 = BitmapFactory.decodeResource(getResources(), R.mipmap.cirl),
                pic3 = BitmapFactory.decodeResource(getResources(), R.mipmap.cirl),
                pic4 = BitmapFactory.decodeResource(getResources(), R.mipmap.cirl),
                pic5 = BitmapFactory.decodeResource(getResources(), R.mipmap.cirl),
                pic6 = BitmapFactory.decodeResource(getResources(), R.mipmap.cirl),
                pic7 = BitmapFactory.decodeResource(getResources(), R.mipmap.cirl)
        };
        list = new ArrayList();

        /*int[] f1 = new int[]{getWidth() / 4 + 75, getHeight() / 8 + 75, getWidth() * 3 / 4 - 150 + 75, getHeight() / 8 + 75};
        int[] f2 = new int[]{getWidth() / 4, getHeight() / 8, getWidth() / 4 + 150, getHeight() / 8 + 150};*/

        int[] f1 = new int[]{500, 500};//中心
        int[] f2 = new int[]{700, 700};
        int[] f3 = new int[]{800, 800};
        int[] f4 = new int[]{800, 800};
        int[] f5 = new int[]{300, 300};
        int[] f6 = new int[]{200, 200};
        int[] f7 = new int[]{100, 100};


        list.add(f1);
        list.add(f2);
        list.add(f3);
        list.add(f4);
        list.add(f5);
        list.add(f6);
        list.add(f7);

        delyList = new ArrayList<>();

    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);


    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);


        canvas.drawColor(Color.BLACK);

        Paint paint = new Paint();


        Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        // 指定图片在屏幕上显示的区域
        Rect dst = new Rect(getWidth() / 4, getHeight() / 8, getWidth() * 3 / 4, getHeight() * 7 / 8);
        // 绘制图片
        canvas.drawBitmap(bitmap, src, dst, null);

        int maxRadus = calcCircleRadius(list);

        //画虚线
        calcPoint(canvas, paint, list, maxRadus);

        //画点间的实线
        paint.setColor(Color.RED);
        paint.setStrokeWidth(10);
        paint.setAntiAlias(true);
        for (int i = 1; i < list.size(); i++) {
            drawLie(canvas, paint, list.get(i));
        }

        //画各点的图
        for (int i = 0; i < list.size(); i++) {
            drawBitmap(canvas, list.get(i), bitmaps[i]);
        }

        //画文字

        paint.setColor(Color.BLACK);
        paint.setStrokeWidth(5);//设置画笔宽度
        paint.setAntiAlias(true);//设置是否使用抗锯齿功能,如果使用,会导致绘图速度变慢
        paint.setStyle(Paint.Style.FILL);//设置绘图样式,对于设置文字和几何图形都有效,可取值有三种 :1、Paint.Style.FILL:填充内部 2、Paint.Style.FILL_AND_STROKE:填充内部和描边 3、Paint.Style.STROKE:仅描边
        paint.setTextAlign(Paint.Align.CENTER);//设置文字对齐方式
        paint.setTextSize(50);//设置文字大小

        for (int i = 1; i < delyList.size(); i++) {
            drawText(canvas, paint, String.valueOf(maxRadus - delyList.get(i)), list.get(i));
        }


        // 虚线圆
        paint.setColor(Color.BLUE);
        paint.setStyle(Paint.Style.STROKE);
        //设置虚线
        PathEffect dashPathEffect = new DashPathEffect(new float[]{5, 5}, 1);
        paint.setPathEffect(dashPathEffect);
        canvas.drawCircle(list.get(0)[0] + 75, list.get(0)[1] + 75, maxRadus, paint);

    }


    private void drawText(Canvas canvas, Paint paint, String text, int[] arr) {

        canvas.drawText(text, arr[0] + 75, arr[1] + 100, paint);
       /* if (arr[0] < getWidth() / 3) {
            canvas.drawText("hello", arr[0]+75 , arr[1]+75, paint);

        } else if (arr[0] > (getWidth() * 2 / 3)) {

            canvas.drawText("hello", arr[0]+75 , arr[1]+75, paint);
        } else {

        }*/

    }

    /**
     * 绘制实线延长线的虚线部分
     *
     * @param canvas
     * @param paint
     * @param list
     * @param radius
     */
    private void calcPoint(Canvas canvas, Paint paint, ArrayList<int[]> list, double radius) {


        for (int i = 1; i < list.size(); i++) {


            int x = (list.get(i)[0] + 75) - (list.get(0)[0] + 75);
            int y = (list.get(i)[1] + 75) - (list.get(0)[1] + 75);
            double radus = (int) Math.sqrt(x * x + y * y);
            //计算半径和点到圆心距离的比例
            double bili = radius / radus;

            //根据比例就可以知道坐标的比例
            //距离之间的比例就是坐标的比例
            int endX = (int) ((list.get(0)[0] + 75) + x * bili);
            int endY = (int) ((list.get(0)[1] + 75) + y * bili);

            paint.setAntiAlias(true);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(10);
            paint.setColor(Color.GRAY);
            //设置虚线
            PathEffect pathEffect = new DashPathEffect(new float[]{5, 5, 5, 5}, 1);
            paint.setPathEffect(pathEffect);
            Path path = new Path();
            path.moveTo(list.get(0)[0] + 75, list.get(0)[1] + 75);
            path.lineTo(endX, endY);
            canvas.drawPath(path, paint);


            //canvas.drawLine(list.get(0)[0] + 75, list.get(0)[1] + 75, endX, endY, paint);
        }

    }

    /**
     * 计算各点和中间点最大的距离,最大距离作为圆的半径
     *
     * @param list
     * @return
     */
    private int calcCircleRadius(ArrayList<int[]> list) {
        int max = 0;
        delyList.clear();

        for (int i = 0; i < list.size(); i++) {
            int x = list.get(0)[0] + 75 - (list.get(i)[0] + 75);
            int y = list.get(0)[1] + 75 - (list.get(i)[1] + 75);
            double radus = Math.sqrt(x * x + y * y);
            delyList.add((int) radus);
            if (radus > max) {
                max = (int) radus;
            }
        }
        return max;


    }

    private void drawLie(Canvas canvas, Paint paint, int[] arr) {

        canvas.drawLine(list.get(0)[0] + 75, list.get(0)[1] + 75, arr[0] + 75, arr[1] + 75, paint);
    }

    private void drawBitmap(Canvas canvas, int[] arr, Bitmap pic) {
        Rect src1 = new Rect(0, 0, pic.getWidth(), pic.getHeight());
        Rect dst1 = new Rect(arr[0], arr[1], arr[0] + 150, arr[1] + 150);
        canvas.drawBitmap(pic, src1, dst1, null);
    }


    float downX = 0;
    float downY = 0;

    //当前拖动的实那个按钮,没有选中状态为-1
    int current = -1;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);


        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();

                for (int i = 0; i < list.size(); i++) {
                    int[] arr = list.get(i);
                    if (downX > arr[0] && downX < arr[0] + 150 && downY > arr[1] && downY < arr[1] + 150) {
                        Log.e("MyView", "第" + i + "个 " + downX + " _ " + downY);
                        current = i;
                        break;
                    }
                }

                break;
            case MotionEvent.ACTION_MOVE:


                if (current != -1) {
                    if (event.getX() < (getWidth() / 4 + 75)) {
                        list.get(current)[0] = getWidth() / 4;
                    } else if (event.getX() > (getWidth() * 3 / 4 - 75)) {
                        list.get(current)[0] = getWidth() * 3 / 4 - 150;
                    } else {
                        list.get(current)[0] = (int) event.getX() - 75;
                    }

                    if (event.getY() < (getHeight() / 4)) {
                        list.get(current)[1] = getHeight() / 4 - 75;
                    } else if (event.getY() > (getHeight() * 3 / 4)) {
                        list.get(current)[1] = getHeight() * 3 / 4 - 75;
                    } else {
                        list.get(current)[1] = (int) event.getY() - 75;
                    }

                    //list.get(current)[0] = (int) event.getX() - 75;
                    //list.get(current)[1] = (int) event.getY() - 75;

                    invalidate();
                }


                break;
            case MotionEvent.ACTION_UP:
                current = -1;

                break;
            case MotionEvent.ACTION_CANCEL:

                break;
        }
        return true;

    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值