绘制虚线并为其设置动画

Draw and animate a dashed line

我有一个全屏 activity 应该是这样的:

白色的大圆圈会有一些文字,我已经做到了,但问题是我不知道如何在图标之间做虚线,他们也想要一点动画图标,所以我假设每个都应该是一个单独的视图,到目前为止我已经这样做了(它不需要看起来完全一样):

那么,我该如何画那条线呢?另外,如果我可以将破折​​号 "run" 横跨线条,那就太棒了。

这是我的 xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rlt_welcome"
    android:layout_weight="9"
    android:background="@drawable/bg"
    >

    <RelativeLayout
        android:layout_width="0dp"
        android:layout_weight="2"
        android:orientation="vertical"
        android:padding="10dp"
        android:layout_height="match_parent">
        <ImageView
            android:layout_width="wrap_content"
            android:id="@+id/img_youtube"
            android:src="@drawable/youtube_circle"
            android:layout_marginTop="60dp"
            android:layout_marginRight="60dp"
            android:layout_height="wrap_content"
            />
        <ImageView
            android:layout_width="wrap_content"
            android:src="@drawable/tablet_circle"
            android:layout_height="wrap_content"
            android:layout_above="@+id/img_stats"
            android:layout_marginRight="30dp"
            android:layout_below="@+id/img_youtube"
            />
        <ImageView
            android:layout_width="wrap_content"
            android:id="@+id/img_stats"
            android:src="@drawable/stats_circle"
            android:layout_height="wrap_content"
            android:layout_marginRight="70dp"
            android:layout_marginBottom="20dp"
            android:layout_alignParentBottom="true"/>

        <ImageView
            android:id="@+id/img_iphone"
            android:layout_width="wrap_content"
            android:src="@drawable/iphone_circle"
            android:layout_height="wrap_content"
            android:layout_marginLeft="60dp"
            />

        <ImageView
            android:layout_width="wrap_content"
            android:src="@drawable/imac_circle"
            android:layout_height="wrap_content"
            android:layout_below="@+id/img_iphone"
            android:layout_marginLeft="70dp"
            android:layout_marginTop="-30dp"
            />
        <ImageView
            android:layout_width="wrap_content"
            android:src="@drawable/webcam_circle"
            android:layout_height="wrap_content"
            android:layout_marginLeft="60dp"
            android:layout_alignParentBottom="true"/>
    </RelativeLayout>
    <RelativeLayout
        android:layout_width="0dp"
        android:layout_weight="5"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center_vertical"
            android:padding="40dp"
            android:textSize="25sp"
            android:textColor="@color/text1"
            android:layout_margin="20dp"
            android:text="Bienvenido"
            android:background="@drawable/flat_circle"
            android:id="@+id/txt_welcome"
            android:layout_centerInParent="true" />

    </RelativeLayout>
    <RelativeLayout
        android:layout_width="0dp"
        android:layout_weight="2"
        android:layout_height="match_parent"
        >
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/arrow_circle"
            android:id="@+id/img_arrow"
            android:layout_alignParentTop="true"
            android:layout_marginRight="60dp"
            />
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/news_circle"
            android:layout_below="@+id/img_arrow"
            android:layout_marginTop="-90dp"
            android:layout_marginRight="2dp"
            android:layout_marginLeft="70dp"
            />
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/line_circle"
            android:id="@+id/img_line"
            android:layout_below="@+id/img_arrow"
            android:layout_marginTop="-10dp"
            android:layout_marginRight="70dp"
            />
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/money_circle"
            android:layout_below="@+id/img_line"
            android:layout_marginRight="6dp"
            android:layout_marginTop="-70dp"
            android:layout_marginLeft="70dp"
            />
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/mouse_circle"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_marginRight="80dp"
            />
    </RelativeLayout>
</LinearLayout>

请检查一下,这可能会对您有所帮助

http://www.rengelbert.com/tutorial.php?id=182

我如何完成这项工作,我制作了一个包含 Canvas 控制器的新 activity,并将位图放置在 canvas 上并用此在它们之间画线,我没有使用任何外部库: 希望有人可以重用一些代码,而不仅仅是被告知 google 它。

MainActivty.java

@Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        relativeMainActivity = (RelativeLayout) findViewById(R.id.rlt_main);
        DisplayMetrics dm = new DisplayMetrics();
        this.getWindowManager().getDefaultDisplay().getMetrics(dm);

        final int heightS = dm.heightPixels;
        final int widthS = dm.widthPixels;

        Log.d("MainActvitiy", "widht:" + widthS);
        myPanel = new Panel(getApplicationContext(),this,widthS, heightS);
        relativeMainActivity.addView(myPanel);

        RelativeLayout RR = new RelativeLayout(this);
        RR.setGravity(Gravity.CENTER);
        relativeMainActivity.addView(RR,400,150);
        RR.setX(0);           
        LayoutInflater myInflater = (LayoutInflater) getApplicationContext().getSystemService(getApplicationContext().LAYOUT_INFLATER_SERVICE);
    }

Panel.java

public class Panel extends SurfaceView implements SurfaceHolder.Callback {

public MainThread thread;
private Background background;
private CircleManager CM;    
public int ScreenWidth;
public int Screenheigt;
private CircleIcon icon1;
private CircleIcon icon2;
private CircleIcon icon3;
//and so on
public MainActivity myMain;


public Panel(Context context, MainActivity _main,  int width , int height) {
    super(context);
    getHolder().addCallback(this);
    this.myMain = _main;
    this.ScreenWidth=width;
    this.Screenheigt=height;
    thread = new MainThread(getHolder(),this);
    background = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.bg), Screenheigt, this);
    CM = new CircleManager( this,context,ScreenWidth);
    CM.setScreen(ScreenWidth, Screenheigt);
    SetIcons();
    CM.setManager();
    setFocusable(true);                     
}

void SetIcons()
{
    icon1 = new CircleIcon(BitmapFactory.decodeResource(getResources(),R.drawable.circle_iphone),39,40);
    icon2 = new CircleIcon(BitmapFactory.decodeResource(getResources(),R.drawable.circle_chat),280,40);
    icon3 = new CircleIcon(BitmapFactory.decodeResource(getResources(),R.drawable.circle_youtube),60,200);
    //and so on

    icon1.myConnections.add(2);
    icon1.myConnections.add(3);
    icon2.myConnections.add(15);
    icon3.myConnections.add(4);
    icon3.myConnections.add(5);
    //and so on



    CM.iconsList.add(icon1);
    CM.iconsList.add(icon2);
    CM.iconsList.add(icon3);
    //and so on
}

void Draw(Canvas canvas){
    if (canvas!=null)
    {
        background.draw(canvas);
        CM.draw(canvas);
        iconEvent.draw(canvas);
    }
}

void Update(float dt)
{
CM.Update(dt);
}


@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {      

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    thread.setRunning(true);
    thread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    boolean retry = true;
    while (retry) 
    {
        try
        {
            thread.join();
            retry=false;
        } 
        catch (InterruptedException e)
        {
        }
    }
}

}

Background.java

public class Background {
    Bitmap BackBitmap;
    int x,y;
    int ScreenHeight;    
    Panel root_panel;

    public Background(Bitmap bitmap , int Screen_h, Panel _panel) {
        this.BackBitmap = bitmap;
        this.x=0;
        this.y=0;
        this.ScreenHeight=Screen_h;        
        root_panel =_panel;
    }

    public void draw(Canvas canvas)
    {        
      canvas.drawBitmap(BackBitmap,x,y, null);       
    }    
}

CircleIcon.java

public class CircleIcon {

private Bitmap bitmap;
private int x;
private int y;
CircleManager circManager;
ArrayList<Integer> myConnections;

public int getX() {
    return x;
}

public void setX(int x) {
    this.x = x;
}

public int getY() {
    return y;
}
public void setY(int y) {
    this.y=y;

}


 public CircleIcon(Bitmap icon, int x, int y) {
    bitmap=icon;
    this.x=x;
    this.y=y;
    myConnections = new ArrayList<>();
}

public ArrayList<Integer> getMyConnections() {
    return myConnections;
}

public void setMyConnections(ArrayList<Integer> myConnections) {
    this.myConnections = myConnections;
}

public void setManager(CircleManager icManager) {
    circManager = icManager;

}

public Bitmap getBitmap() 
{
    return bitmap;
}

public void setBitmap(Bitmap bitmap) {
    this.bitmap = bitmap;
}

public void draw(Canvas canvas) {

    canvas.drawBitmap(bitmap, x, y, null);      
}

public void update()
{
        // x=+1; example
}                   
}

CircleManager.java

public class CircleManager {

    Bitmap icons;
    int screenWidth;        
    int hour;
    int min;        
    Context myContext;      
    int ScreenWidht;
    public Panel myPanel;   
    public ArrayList<CircleIcon> iconsList;


    public CircleManager(Panel _Panel, Context context,int screenW) {       
        this.myPanel = _Panel;      
        this.screenWidth = screenW;
        this.myContext = context;
        iconsList = new ArrayList<CircleIcon>(); 
    }

    public void setScreen(int screenWidth, int screenHeight) 
    {
        this.ScreenWidht=screenWidth;
    }

    public void draw(Canvas canvas)
    {
        drawLines(canvas);
        for(CircleIcon myIcon: iconsList)
        {           
            myIcon.draw(canvas);            
        }

    }

    public void Update(float dt)
    {
        //some animation updates
    }


    public void drawLines(Canvas canvas)
    {
       Paint mPaint = new Paint();
       mPaint.setColor(Color.WHITE);
       mPaint.setStyle(Paint.Style.STROKE);
       mPaint.setStrokeWidth(2);
       mPaint.setPathEffect(new DashPathEffect(new float[]{7, 5}, 0));

        for (CircleIcon myIcon: iconsList)
        {           
            for( int connectedIcon: myIcon.getMyConnections())
            {
                   Path mPath;
                   mPath = new Path();
                   mPath.moveTo(myIcon.getX()+myIcon.getBitmap().getWidth()/2, myIcon.getY()+myIcon.getBitmap().getHeight()/2);
                   mPath.lineTo(iconsList.get(connectedIcon-1).getX()+myIcon.getBitmap().getWidth()/2, iconsList.get(connectedIcon-1).getY()+myIcon.getBitmap().getHeight()/2);
                   canvas.drawPath(mPath, mPaint);
            }
        }   
    }

    public void setManager()
    {
        for(CircleIcon myIcon: iconsList)
        {           
            myIcon.setManager(this);            
        }
    }

}