├── settings.gradle
├── LauncherView.gif
├── app
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── colors.xml
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── logo.png
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── slogan.png
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── drawable
│ │ │ │ ├── shape_circle_red.xml
│ │ │ │ ├── shape_circle_blue.xml
│ │ │ │ ├── shape_circle_purple.xml
│ │ │ │ └── shape_circle_yellow.xml
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ └── layout
│ │ │ │ ├── activity_main.xml
│ │ │ │ └── widget_load_view.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── rongyi
│ │ │ └── diamond
│ │ │ └── animation
│ │ │ ├── launcher
│ │ │ ├── Utils.java
│ │ │ ├── ViewPath.java
│ │ │ ├── ViewPoint.java
│ │ │ ├── ViewPathEvaluator.java
│ │ │ └── LauncherView.java
│ │ │ └── MainActivity.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── rongyi
│ │ │ └── diamond
│ │ │ └── animation
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── rongyi
│ │ └── diamond
│ │ └── animation
│ │ └── ApplicationTest.java
├── proguard-rules.pro
└── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── README.md
└── gradle.properties
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/LauncherView.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diamondlin2016/LauncherView/HEAD/LauncherView.gif
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | animation
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diamondlin2016/LauncherView/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diamondlin2016/LauncherView/HEAD/app/src/main/res/mipmap-xhdpi/logo.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/slogan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diamondlin2016/LauncherView/HEAD/app/src/main/res/mipmap-xxhdpi/slogan.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diamondlin2016/LauncherView/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diamondlin2016/LauncherView/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diamondlin2016/LauncherView/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diamondlin2016/LauncherView/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/diamondlin2016/LauncherView/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LauncherView
2 |
3 | 
4 |
5 |
6 | [十分钟搞定酷炫动画,Android自定义 View 入门](http://www.jianshu.com/p/138ad32540ce)
7 |
8 | test
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_circle_red.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_circle_blue.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_circle_purple.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_circle_yellow.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/test/java/com/rongyi/diamond/animation/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.rongyi.diamond.animation;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/rongyi/diamond/animation/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.rongyi.diamond.animation;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
8 |
9 | #fa007a
10 | #935fe7
11 | #f9b11f
12 | #009cfaΩ
13 |
14 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/apple/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 24
5 | buildToolsVersion "24.0.2"
6 |
7 | defaultConfig {
8 | applicationId "com.rongyi.diamond.animation"
9 | minSdkVersion 15
10 | targetSdkVersion 24
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | testCompile 'junit:junit:4.12'
25 | compile 'com.android.support:appcompat-v7:24.2.1'
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/app/src/main/java/com/rongyi/diamond/animation/launcher/Utils.java:
--------------------------------------------------------------------------------
1 | package com.rongyi.diamond.animation.launcher;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * Author: Diamond_Lin
7 | * Version V1.0
8 | * Date: 16/10/17 上午11:28
9 | * Description:
10 | * Modification History:
11 | * Date Author Version Description
12 | * -----------------------------------------------------------------------------------
13 | * 16/10/17 Diamond_Lin 1.0 1.0
14 | * Why & What is modified:
15 | */
16 | public class Utils {
17 | /**
18 | * dp转px
19 | *
20 | * @param context 上下文
21 | * @param dpValue dp值
22 | * @return px值
23 | */
24 | public static int dp2px(Context context, float dpValue) {
25 | final float scale = context.getResources().getDisplayMetrics().density;
26 | return (int) (dpValue * scale + 0.5f);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rongyi/diamond/animation/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.rongyi.diamond.animation;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.view.View;
6 |
7 | import com.rongyi.diamond.animation.launcher.LauncherView;
8 |
9 | public class MainActivity extends AppCompatActivity {
10 |
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_main);
15 | final LauncherView launcherView = (LauncherView) findViewById(R.id.load_view);
16 | // new Handler().postDelayed(new Runnable() {
17 | // @Override
18 | // public void run() {
19 | //
20 | // }
21 | // },500);
22 |
23 | findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {
24 | @Override
25 | public void onClick(View v) {
26 | launcherView.start();
27 | }
28 | });
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/widget_load_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
16 |
17 |
18 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rongyi/diamond/animation/launcher/ViewPath.java:
--------------------------------------------------------------------------------
1 | package com.rongyi.diamond.animation.launcher;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collection;
5 |
6 | /**
7 | * Author: Diamond_Lin
8 | * Version V1.0
9 | * Date: 16/10/18 下午6:47
10 | * Description:
11 | * Modification History:
12 | * Date Author Version Description
13 | * -----------------------------------------------------------------------------------
14 | * 16/10/18 Diamond_Lin 1.0 1.0
15 | * Why & What is modified:
16 | */
17 | public class ViewPath {
18 | public static final int MOVE = 0;
19 | public static final int LINE = 1;
20 | public static final int QUAD = 2;
21 | public static final int CURVE = 3;
22 |
23 | private ArrayList mPoints;
24 |
25 |
26 | public ViewPath() {
27 | mPoints = new ArrayList<>();
28 | }
29 |
30 | public void moveTo(float x, float y){
31 | mPoints.add(ViewPoint.moveTo(x,y,MOVE));
32 | }
33 |
34 | public void lineTo(float x,float y){
35 | mPoints.add(ViewPoint.lineTo(x,y,LINE));
36 | }
37 |
38 | public void curveTo(float x,float y,float x1,float y1,float x2,float y2){
39 | mPoints.add(ViewPoint.curveTo(x,y,x1,y1,x2,y2,CURVE));
40 | }
41 |
42 | public void quadTo(float x,float y,float x1,float y1){
43 | mPoints.add(ViewPoint.quadTo(x,y,x1,y1,QUAD));
44 | }
45 |
46 | public Collection getPoints(){
47 | return mPoints;
48 | }
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rongyi/diamond/animation/launcher/ViewPoint.java:
--------------------------------------------------------------------------------
1 | package com.rongyi.diamond.animation.launcher;
2 |
3 | /**
4 | * Author: Diamond_Lin
5 | * Version V1.0
6 | * Date: 16/10/18 下午6:47
7 | * Description:
8 | * Modification History:
9 | * Date Author Version Description
10 | * -----------------------------------------------------------------------------------
11 | * 16/10/18 Diamond_Lin 1.0 1.0
12 | * Why & What is modified:
13 | */
14 | public class ViewPoint {
15 | float x ,y;
16 |
17 | float x1,y1;
18 |
19 | float x2,y2;
20 |
21 | int operation;
22 |
23 | public ViewPoint(float x, float y) {
24 | this.x = x;
25 | this.y = y;
26 | }
27 |
28 | public static ViewPoint moveTo(float x, float y, int operation){
29 | return new ViewPoint(x,y,operation);
30 | }
31 |
32 | public static ViewPoint lineTo(float x, float y, int operation){
33 | return new ViewPoint(x,y,operation);
34 | }
35 | public static ViewPoint curveTo(float x, float y,float x1,float y1,float x2,float y2, int operation){
36 | return new ViewPoint(x,y,x1,y1,x2,y2,operation);
37 | }
38 |
39 | public static ViewPoint quadTo(float x, float y,float x1,float y1, int operation){
40 | return new ViewPoint(x,y,x1,y1,operation);
41 | }
42 |
43 |
44 |
45 | private ViewPoint(float x, float y, int operation) {
46 | this.x = x;
47 | this.y = y;
48 | this.operation = operation;
49 | }
50 |
51 | public ViewPoint(float x, float y, float x1, float y1, int operation) {
52 | this.x = x;
53 | this.y = y;
54 | this.x1 = x1;
55 | this.y1 = y1;
56 | this.operation = operation;
57 | }
58 |
59 | public ViewPoint(float x, float y, float x1, float y1, float x2, float y2, int operation) {
60 | this.x = x;
61 | this.y = y;
62 | this.x1 = x1;
63 | this.y1 = y1;
64 | this.x2 = x2;
65 | this.y2 = y2;
66 | this.operation = operation;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rongyi/diamond/animation/launcher/ViewPathEvaluator.java:
--------------------------------------------------------------------------------
1 | package com.rongyi.diamond.animation.launcher;
2 |
3 | import android.animation.TypeEvaluator;
4 |
5 | /**
6 | * Author: Diamond_Lin
7 | * Version V1.0
8 | * Date: 16/10/18 下午6:48
9 | * Description:
10 | * Modification History:
11 | * Date Author Version Description
12 | * -----------------------------------------------------------------------------------
13 | * 16/10/18 Diamond_Lin 1.0 1.0
14 | * Why & What is modified:
15 | */
16 | public class ViewPathEvaluator implements TypeEvaluator {
17 |
18 |
19 | public ViewPathEvaluator() {
20 | }
21 |
22 | @Override
23 | public ViewPoint evaluate(float t, ViewPoint startValue, ViewPoint endValue) {
24 |
25 | float x ,y;
26 |
27 | float startX,startY;
28 |
29 | if(endValue.operation == ViewPath.LINE){
30 |
31 | startX = (startValue.operation==ViewPath.QUAD)?startValue.x1:startValue.x;
32 |
33 | startX = (startValue.operation == ViewPath.CURVE)?startValue.x2:startX;
34 |
35 | startY = (startValue.operation==ViewPath.QUAD)?startValue.y1:startValue.y;
36 |
37 | startY = (startValue.operation == ViewPath.CURVE)?startValue.y2:startY;
38 |
39 | x = startX + t * (endValue.x - startX);
40 | y = startY+ t * (endValue.y - startY);
41 |
42 |
43 |
44 | }else if(endValue.operation == ViewPath.CURVE){
45 |
46 |
47 | startX = (startValue.operation==ViewPath.QUAD)?startValue.x1:startValue.x;
48 | startY = (startValue.operation==ViewPath.QUAD)?startValue.y1:startValue.y;
49 |
50 | float oneMinusT = 1 - t;
51 |
52 |
53 | x = oneMinusT * oneMinusT * oneMinusT * startX +
54 | 3 * oneMinusT * oneMinusT * t * endValue.x +
55 | 3 * oneMinusT * t * t * endValue.x1+
56 | t * t * t * endValue.x2;
57 |
58 | y = oneMinusT * oneMinusT * oneMinusT * startY +
59 | 3 * oneMinusT * oneMinusT * t * endValue.y +
60 | 3 * oneMinusT * t * t * endValue.y1+
61 | t * t * t * endValue.y2;
62 |
63 |
64 | }else if(endValue.operation == ViewPath.MOVE){
65 |
66 | x = endValue.x;
67 | y = endValue.y;
68 |
69 |
70 | }else if(endValue.operation == ViewPath.QUAD){
71 |
72 |
73 | startX = (startValue.operation==ViewPath.CURVE)?startValue.x2:startValue.x;
74 | startY = (startValue.operation==ViewPath.CURVE)?startValue.y2:startValue.y;
75 |
76 | float oneMinusT = 1 - t;
77 | x = oneMinusT * oneMinusT * startX +
78 | 2 * oneMinusT * t * endValue.x +
79 | t * t * endValue.x1;
80 |
81 | y = oneMinusT * oneMinusT * startY +
82 | 2 * oneMinusT * t * endValue.y +
83 | t * t * endValue.y1;
84 |
85 |
86 | }else {
87 | x = endValue.x;
88 | y = endValue.y;
89 | }
90 |
91 |
92 | return new ViewPoint(x,y);
93 | }
94 | }
95 |
96 |
--------------------------------------------------------------------------------
/app/src/main/java/com/rongyi/diamond/animation/launcher/LauncherView.java:
--------------------------------------------------------------------------------
1 | package com.rongyi.diamond.animation.launcher;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorListenerAdapter;
5 | import android.animation.AnimatorSet;
6 | import android.animation.ObjectAnimator;
7 | import android.animation.ValueAnimator;
8 | import android.content.Context;
9 | import android.os.Handler;
10 | import android.util.AttributeSet;
11 | import android.util.Log;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.view.animation.AccelerateDecelerateInterpolator;
15 | import android.widget.ImageView;
16 | import android.widget.RelativeLayout;
17 |
18 | import com.rongyi.diamond.animation.R;
19 |
20 | /**
21 | * Author: Diamond_Lin
22 | * Version V1.0
23 | * Date: 16/10/18 下午3:30
24 | * Description:
25 | * Modification History:
26 | * Date Author Version Description
27 | * -----------------------------------------------------------------------------------
28 | * 16/10/18 Diamond_Lin 1.0 1.0
29 | * Why & What is modified:
30 | */
31 | public class LauncherView extends RelativeLayout {
32 | private int mHeight;
33 | private int mWidth;
34 | private int dp80 = Utils.dp2px(getContext(), 80);
35 | private boolean mHasStart;
36 |
37 | public LauncherView(Context context) {
38 | super(context);
39 | }
40 |
41 | public LauncherView(Context context, AttributeSet attrs) {
42 | super(context, attrs);
43 | }
44 |
45 | public LauncherView(Context context, AttributeSet attrs, int defStyleAttr) {
46 | super(context, attrs, defStyleAttr);
47 | }
48 |
49 | ImageView red, purple, yellow, blue;
50 |
51 | private void init() {
52 |
53 | LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
54 | lp.addRule(CENTER_HORIZONTAL, TRUE);//这里的TRUE 要注意 不是true
55 | lp.addRule(CENTER_VERTICAL, TRUE);
56 | lp.setMargins(0, 0, 0, dp80);
57 |
58 | purple = new ImageView(getContext());
59 | purple.setLayoutParams(lp);
60 | purple.setImageResource(R.drawable.shape_circle_purple);
61 | addView(purple);
62 |
63 | yellow = new ImageView(getContext());
64 | yellow.setLayoutParams(lp);
65 | yellow.setImageResource(R.drawable.shape_circle_yellow);
66 | addView(yellow);
67 |
68 | blue = new ImageView(getContext());
69 | blue.setLayoutParams(lp);
70 | blue.setImageResource(R.drawable.shape_circle_blue);
71 | addView(blue);
72 |
73 | red = new ImageView(getContext());
74 | red.setLayoutParams(lp);
75 | red.setImageResource(R.drawable.shape_circle_red);
76 | addView(red);
77 |
78 | setAnimation(red, redPath1);
79 | setAnimation(purple, purplePath1);
80 | setAnimation(yellow, yellowPath1);
81 | setAnimation(blue, bluePath1);
82 |
83 | }
84 |
85 | ViewPath redPath1, purplePath1, yellowPath1, bluePath1;
86 |
87 | private void initPath() {
88 | redPath1 = new ViewPath(); //偏移坐标
89 | redPath1.moveTo(0, 0);
90 | redPath1.lineTo(mWidth / 5 - mWidth / 2, 0);
91 | redPath1.curveTo(-700, -mHeight / 2, mWidth / 3 * 2, -mHeight / 3 * 2, 0, -dp80);
92 |
93 | purplePath1 = new ViewPath(); //偏移坐标
94 | purplePath1.moveTo(0, 0);
95 | purplePath1.lineTo(mWidth / 5 * 2 - mWidth / 2, 0);
96 | purplePath1.curveTo(-300, -mHeight / 2, mWidth, -mHeight / 9 * 5, 0, -dp80);
97 |
98 | yellowPath1 = new ViewPath(); //偏移坐标
99 | yellowPath1.moveTo(0, 0);
100 | yellowPath1.lineTo(mWidth / 5 * 3 - mWidth / 2, 0);
101 | yellowPath1.curveTo(300, mHeight, -mWidth, -mHeight / 9 * 5, 0, -dp80);
102 |
103 | bluePath1 = new ViewPath(); //偏移坐标
104 | bluePath1.moveTo(0, 0);
105 | bluePath1.lineTo(mWidth / 5 * 4 - mWidth / 2, 0);
106 | bluePath1.curveTo(700, mHeight / 3 * 2, -mWidth / 2, mHeight / 2, 0, -dp80);
107 |
108 | }
109 |
110 | @Override
111 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
112 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
113 | mWidth = getMeasuredWidth();
114 | mHeight = getMeasuredHeight();
115 | initPath();
116 | }
117 |
118 |
119 | public void start() {
120 | removeAllViews();
121 | init();
122 | redAll.start();
123 | yellowAll.start();
124 | purpleAll.start();
125 | blueAll.start();
126 |
127 | new Handler().postDelayed(new Runnable() {
128 | @Override
129 | public void run() {
130 | showLogo();
131 | }
132 | }, 2400);
133 | }
134 |
135 | private void setAnimation(final ImageView target, ViewPath path1) {
136 | //路径
137 | ObjectAnimator anim1 = ObjectAnimator.ofObject(new ViewObj(target), "fabLoc", new ViewPathEvaluator(), path1.getPoints().toArray());
138 | anim1.setInterpolator(new AccelerateDecelerateInterpolator());
139 | anim1.setDuration(2600);
140 | //组合添加缩放透明效果
141 | addAnimation(anim1, target);
142 | }
143 |
144 |
145 | AnimatorSet redAll, purpleAll, yellowAll, blueAll;
146 |
147 | private void addAnimation(ObjectAnimator animator1, final ImageView target) {
148 | ValueAnimator valueAnimator = ValueAnimator.ofFloat(1, 1000);
149 | valueAnimator.setDuration(1800);
150 | valueAnimator.setStartDelay(1000);
151 | valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
152 | @Override
153 | public void onAnimationUpdate(ValueAnimator animation) {
154 | float value = (float) animation.getAnimatedValue();
155 | float alpha = 1 - value / 2000;
156 | float scale = getScale(target) - 1;
157 | if (value <= 500) {
158 | scale = 1 + (value / 500) * scale;
159 | } else {
160 | scale = 1 + ((1000 - value) / 500) * scale;
161 | }
162 | target.setScaleX(scale);
163 | target.setScaleY(scale);
164 | target.setAlpha(alpha);
165 | }
166 | });
167 | valueAnimator.addListener(new AnimEndListener(target));
168 | if (target == red) {
169 | redAll = new AnimatorSet();
170 | redAll.playTogether(animator1, valueAnimator);
171 | }
172 | if (target == blue) {
173 | blueAll = new AnimatorSet();
174 | blueAll.playTogether(animator1, valueAnimator);
175 | }
176 | if (target == purple) {
177 | purpleAll = new AnimatorSet();
178 | purpleAll.playTogether(animator1, valueAnimator);
179 | }
180 | if (target == yellow) {
181 | yellowAll = new AnimatorSet();
182 | yellowAll.playTogether(animator1, valueAnimator);
183 | }
184 |
185 | }
186 |
187 |
188 | private float getScale(ImageView target) {
189 | if (target == red)
190 | return 3.0f;
191 | if (target == purple)
192 | return 2.0f;
193 | if (target == yellow)
194 | return 4.5f;
195 | if (target == blue)
196 | return 3.5f;
197 | return 2f;
198 | }
199 |
200 |
201 | private void showLogo() {
202 | View view = View.inflate(getContext(), R.layout.widget_load_view, this);
203 | View logo = view.findViewById(R.id.iv_logo);
204 | final View slogo = view.findViewById(R.id.iv_slogo);
205 | ObjectAnimator alpha = ObjectAnimator.ofFloat(logo, View.ALPHA, 0f, 1f);
206 | alpha.setDuration(800);
207 |
208 | alpha.start();
209 | new Handler().postDelayed(new Runnable() {
210 | @Override
211 | public void run() {
212 | ObjectAnimator alpha = ObjectAnimator.ofFloat(slogo, View.ALPHA, 0f, 1f);
213 | alpha.setDuration(200);
214 | alpha.start();
215 | }
216 | }, 400);
217 |
218 | }
219 |
220 | private class AnimEndListener extends AnimatorListenerAdapter {
221 | private View target;
222 |
223 | public AnimEndListener(View target) {
224 | this.target = target;
225 | }
226 |
227 | @Override
228 | public void onAnimationEnd(Animator animation) {
229 | super.onAnimationEnd(animation);
230 | removeView((target));
231 | }
232 | }
233 |
234 |
235 | public class ViewObj {
236 | private final ImageView red;
237 |
238 | public ViewObj(ImageView red) {
239 | this.red = red;
240 | }
241 |
242 | public void setFabLoc(ViewPoint newLoc) {
243 | red.setTranslationX(newLoc.x);
244 | red.setTranslationY(newLoc.y);
245 | }
246 | }
247 |
248 |
249 | }
250 |
251 |
252 |
--------------------------------------------------------------------------------