The size is 1. Draw a circle. Here I sent 4 groups of data, which used radian calculation and Angle calculation in the code Animation dynamic drawing graphics nonsense no more to say direct code code is not much direct copy of the following view can be

import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; import android.view.animation.LinearInterpolator; import java.util.ArrayList; import java.util.List; /** * @since 1.0 * <p> custom View * chendu 2018/6/1 */ public class DemoTowerView extends View {/** ** private int mBorderWidth = 2; private int mTextColor = Color.GRAY; private int mTextSize = 12; /** * private Paint mPaint; /** * private int mWidth; private int mHeight; privatefloat[] currentAngle = new float[6]. Private int[] greenx = new int[6]; Private int[] greeny = new int[6]; // Green dot dynamic distance y // The following three parameters are so that when the second parameter is passed, the graph can continue to move from the last state instead of starting from 0float[] currentAnglelast = new float[6]. Private int[] greenxLast = new int[6]; Private int[] greenyLast = new int[6]; Private int[] mwidthLast = new int[6]; private int[] mwidthLast = new int[6]; Private int[] prevMoveWidth = new int[6]; List<Towerbean> List = new ArrayList<>(); private int cx, cy, leve; private int width = this.getResources().getDisplayMetrics().widthPixels / 6; //getMeasuredWidth()/6; Public DemoTowerView(Context Context) {this(Context, null); } public DemoTowerView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public DemoTowerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint = new Paint(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec);if (widthMode == MeasureSpec.EXACTLY) {
            mWidth = widthSize;
        } else {
            int desire = getPaddingLeft() + getPaddingRight() + (int) TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP, 200, getResources().getDisplayMetrics());
            mWidth = Math.min(desire, widthSize);
        }
        if (heightMode == MeasureSpec.EXACTLY) {
            mHeight = heightSize;
        } else{ int desire = getPaddingTop() + getPaddingBottom() + (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 200, getResources().getDisplayMetrics()); mHeight = Math.min(desire, heightSize); } mWidth = Math.min(mWidth, mHeight); // Take the minimum value to prevent errors in drawing contentsetMeasuredDimension(mWidth, mWidth); } @override protected void onDraw(final Canvas Canvas) {/** * cx = getPaddingLeft() + (getMeasuredWidth() - getPaddingLeft() - getPaddingRight()) / 2; cy = getPaddingTop() + (getMeasuredHeight() - getPaddingTop() - getPaddingBottom()) / 2; width = Math.min(getWidth() / 6, getHeight() / 6); // Radius // draw the cross coordinate mPaint. SetColor (color.ltgray); canvas.drawLine(cx, 0, cx, mHeight, mPaint); canvas.drawLine(0, cy, mWidth, cy, mPaint); mPaint.setTextAlign(Paint.Align.CENTER); canvas.drawText("0 °", cx, 15, mPaint);
        canvas.drawText("90 °", mWidth - 15, cy, mPaint);
        canvas.drawText("180 °", cx, mWidth - 15, mPaint);
        canvas.drawText("270 °", 15, cy, mPaint);

        mPaint.setAntiAlias(true); // Remove edge aliasing to optimize rendering effectif(list ! = null && list.size() > 0) {for(int i = 0; i < list.size(); i++) { leve = leve ! = 0? list.get(0).twlong : width; Int twocx = cx + (int) (width * list.get(I). Distance/leve * math.sin (math.pi *) list.get(i).angle / 180)); Width * list.get(I).distance/leve * math.cos (math.pi * list.get(I).angle / 180)); / / circle yif(I == 0) {// Draw the inner and outer circle of the monitoring tower mPaint. SetColor (color.black); mPaint.setStyle(Paint.Style.STROKE); // Set hollow mPaint. SetStrokeWidth (mBorderWidth); DrawCircle (cx, cy, width, mPaint); // Inner circle black // Inner circle green mPaint. SetStyle (paint.style.fill); // Set solid mPaint. SetColor (color.parsecolor ("#B2C8F9D2"));
                    canvas.drawCircle(cx, cy, width - mBorderWidth, mPaint);
                } else{// Base on the center * degree of the outer circle mPaint. SetColor (color.black); mPaint.setStyle(Paint.Style.STROKE); // Set hollow mPaint. SetStrokeWidth (mBorderWidth); DrawCircle (twocx, twocy, width * list.get(I). Twlong/leve, mPaint); drawCircle(twocx, twocy, width * list.get(I). // Paint aint. SetStyle (paint.style.fill); // draw the tower arm line 2 mPaint. SetColor (color.black); canvas.save(); Rotate (currentAngle[I], twocx, twocy); canvas.drawRect(twocx - TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()), twocy - width * list.get(i).twlong / leve + TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()), twocx + TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()), twocy + TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics()), mPaint); canvas.restore(); // Center, RED 2 mPaint. SetColor (color.red); canvas.drawCircle(twocx, twocy, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics()), mPaint); // mPaint. SetColor (color.green); canvas.drawCircle(twocx + greenx[i], twocy - greeny[i], TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics()), mPaint); SetColor (mTextColor); mPaint.setTextSize(mTextSize); mPaint.setTextAlign(Paint.Align.CENTER); canvas.drawText(list.get(i).name, twocx, twocy - (width * list.get(i).twlong / (2 * leve)), mPaint); }} /** * set data ** @param list */ public voidsetDate(List<Towerbean> list) {
        this.list = list;
        if(list ! = null && list.size() > 0)for(int i = 0; i < list.size(); i++) { currentAnglelast[i] = currentAngle[i]; greenxlast[i] = greenx[i]; greenylast[i] = greeny[i]; mwidthlast[i] = prevmovewidth[i]; leve = list.get(0).twlong; int mmovewidth = width * list.get(i).movewidth / leve; StartCirMotion (list.get(I).twturnAngle, math.abs (mmoveWidth - mwidthLast [I]), I); }} @param color */ public void setmTextColor(int color) {mTextColor = color; } @param size */ public void setmTextSize(int size) {mTextSize = size; } /** * rotation animation */ private void startCirMotion(finalfloatAngle, final int mwidth, final int i) { ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f); animator.setDuration((long) 3000); / / animation time 3 s animator. AddUpdateListener (new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Float t = (Float) animation.getAnimatedValue();
                currentAngle[i] = t * Angle + currentAnglelast[i];
                float r = t * mwidth + mwidthlast[i];
                greenx[i] = (int) (r * Math.sin(Math.PI * currentAngle[i] / 180));
                greeny[i] = (int) (r * Math.cos(Math.PI * currentAngle[i] / 180));
//                Log.e("CD"."debug:(x,y) = " + greenx[i] + ","+ greeny[i]); invalidate(); prevmovewidth[i] = (int) (t * mwidth); }}); animator.setInterpolator(new LinearInterpolator()); // Rotate animator.start(); }}Copy the code

The data object class is as follows

public class Towerbean {

    floatangle; // Int twlong; / / arm lengthfloattwturnAngle; Int moveWidth; // int distance; String name; }}Copy the code

Reference in the layout

<? xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <tower.DemoTowerView
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="10dp"
        android:text="Tower Crane Animation"/>

</LinearLayout>
Copy the code

The Activity is used in

view = findViewById(R.id.view); List<Towerbean> list = new ArrayList<>(); Towerbean = new Towerbean(); Towerbean = new Towerbean(); bean.angle = 0; bean.twlong = 100; bean.twturnAngle = -30; bean.movewidth = 80; bean.distance = 0; bean.name ="Tower machine Casa pink play 1";
        list.add(bean);
        
        view.setDate(list);
Copy the code

Last thought! This control to modify the origin can achieve similar to radar scanning to remove leverage to add a few points can achieve similar star map around their own thought so much hope that the above code is useful to you!