diff --git a/README.md b/README.md
index 8c7b73b..d06f320 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,9 @@
# Android View Animations [](https://travis-ci.org/daimajia/AndroidViewAnimations)
-[](https://gitter.im/daimajia/AndroidViewAnimations?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[](https://gitter.im/daimajia/AndroidViewAnimations?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+
+[](https://insight.io/github.com/daimajia/AndroidViewAnimations)
One day, I saw [an iOS library](https://github.com/ArtFeel/AFViewShaker), which is a view shaker, it's very beautiful. I think Android also need one, and should be better.
@@ -24,7 +27,7 @@ For making animations more real, I created another project named [Android Easing
dependencies {
compile 'com.android.support:support-compat:25.1.1'
compile 'com.daimajia.easing:library:2.0@aar'
- compile 'com.daimajia.androidanimations:library:2.0@aar'
+ compile 'com.daimajia.androidanimations:library:2.3@aar'
}
```
#### Maven
@@ -38,7 +41,7 @@ dependencies {
com.daimajia.androidanimation
library
- 2.0
+ 2.3
com.daimajia.easing
@@ -47,13 +50,6 @@ dependencies {
```
-#### Eclipse
-
-Download the following jars, and copy them into your `libs` directory.
-
-- [`AndroidEasingFunctions-1.0.0`](https://github.com/daimajia/AndroidViewAnimations/releases/download/v1.0.6/AndroidEasingFunctions-1.0.0.jar)
-- [`AndroidViewAnimations-1.1.3`](https://github.com/daimajia/AndroidViewAnimations/releases/download/v1.1.3/AndroidViewAnimations-1.1.3.jar)
-
## Step 2
Just like play Yo-yo.
@@ -61,6 +57,7 @@ Just like play Yo-yo.
```java
YoYo.with(Techniques.Tada)
.duration(700)
+ .repeat(5)
.playOn(findViewById(R.id.edit_area));
```
@@ -99,12 +96,12 @@ YoYo.with(Techniques.Tada)
Welcome contribute your amazing animation effect. :-D
-#Thanks
+# Thanks
- [AFViewShaker](https://github.com/ArtFeel/AFViewShaker)
- [Animate.css](https://github.com/daneden/animate.css)
-#About me
+# About me
A student in mainland China.
diff --git a/demo/build.gradle b/demo/build.gradle
index 0bceb40..02ec5a9 100644
--- a/demo/build.gradle
+++ b/demo/build.gradle
@@ -7,8 +7,8 @@ android {
applicationId "com.daimajia.androidanimations"
minSdkVersion 14
targetSdkVersion 25
- versionCode 2
- versionName "2.0"
+ versionCode 3
+ versionName "3.0"
}
buildTypes {
release {
diff --git a/demo/src/main/java/com/daimajia/androidanimations/MyActivity.java b/demo/src/main/java/com/daimajia/androidanimations/MyActivity.java
index 4e7483a..e045984 100644
--- a/demo/src/main/java/com/daimajia/androidanimations/MyActivity.java
+++ b/demo/src/main/java/com/daimajia/androidanimations/MyActivity.java
@@ -27,7 +27,7 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
- mListView = (ListView)findViewById(R.id.list_items);
+ mListView = (ListView) findViewById(R.id.list_items);
mTarget = findViewById(R.id.hello_world);
mAdapter = new EffectAdapter(this);
@@ -36,39 +36,43 @@ protected void onCreate(Bundle savedInstanceState) {
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
- Techniques technique = (Techniques)view.getTag();
- rope = YoYo.with(technique)
- .duration(1200)
- .interpolate(new AccelerateDecelerateInterpolator())
- .withListener(new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
-
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
-
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- Toast.makeText(MyActivity.this, "canceled", Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
-
- }
- })
- .playOn(mTarget);
+ if (rope != null) {
+ rope.stop(true);
+ }
+ Techniques technique = (Techniques) view.getTag();
+ rope = YoYo.with(technique)
+ .duration(1200)
+ .repeat(YoYo.INFINITE)
+ .pivot(YoYo.CENTER_PIVOT, YoYo.CENTER_PIVOT)
+ .interpolate(new AccelerateDecelerateInterpolator())
+ .withListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ Toast.makeText(MyActivity.this, "canceled previous animation", Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+
+ }
+ })
+ .playOn(mTarget);
}
});
findViewById(R.id.hello_world).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (rope != null) {
- rope.stop(true);
+ rope.stop(true);
}
}
});
@@ -76,7 +80,7 @@ public void onClick(View v) {
@Override
public void onWindowFocusChanged(boolean hasFocus) {
- if(hasFocus){
+ if (hasFocus) {
rope = YoYo.with(Techniques.FadeIn).duration(1000).playOn(mTarget);// after start,just click mTarget view, rope is not init
}
}
@@ -96,7 +100,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
- startActivity(new Intent(this,ExampleActivity.class));
+ startActivity(new Intent(this, ExampleActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
diff --git a/gradle.properties b/gradle.properties
index 56d6972..5c244a6 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -18,8 +18,8 @@
# org.gradle.parallel=true
-VERSION_NAME=2.0
-VERSION_CODE=20
+VERSION_NAME=2.3
+VERSION_CODE=31
GROUP=com.daimajia.androidanimations
POM_DESCRIPTION=Collect android animations
diff --git a/library/build.gradle b/library/build.gradle
index 1c5d4ea..f983eb0 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -6,8 +6,8 @@ android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 25
- versionCode 20
- versionName "2.0"
+ versionCode 31
+ versionName "2.3"
}
buildTypes {
release {
diff --git a/library/src/main/java/com/daimajia/androidanimations/library/BaseViewAnimator.java b/library/src/main/java/com/daimajia/androidanimations/library/BaseViewAnimator.java
index b4a25ba..1b0eaf0 100644
--- a/library/src/main/java/com/daimajia/androidanimations/library/BaseViewAnimator.java
+++ b/library/src/main/java/com/daimajia/androidanimations/library/BaseViewAnimator.java
@@ -26,6 +26,7 @@
import android.animation.Animator;
import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.animation.Interpolator;
@@ -36,7 +37,10 @@ public abstract class BaseViewAnimator {
public static final long DURATION = 1000;
private AnimatorSet mAnimatorSet;
+
private long mDuration = DURATION;
+ private int mRepeatTimes = 0;
+ private int mRepeatMode = ValueAnimator.RESTART;
{
mAnimatorSet = new AnimatorSet();
@@ -55,6 +59,11 @@ public void animate() {
start();
}
+ public void restart() {
+ mAnimatorSet = mAnimatorSet.clone();
+ start();
+ }
+
/**
* reset the view to default status
*
@@ -69,14 +78,18 @@ public void reset(View target) {
ViewCompat.setRotation(target, 0);
ViewCompat.setRotationY(target, 0);
ViewCompat.setRotationX(target, 0);
- ViewCompat.setPivotX(target, target.getMeasuredWidth() / 2.0f);
- ViewCompat.setPivotY(target, target.getMeasuredHeight() / 2.0f);
}
/**
* start to animate
*/
public void start() {
+ for (Animator animator : mAnimatorSet.getChildAnimations()) {
+ if (animator instanceof ValueAnimator) {
+ ((ValueAnimator) animator).setRepeatCount(mRepeatTimes);
+ ((ValueAnimator) animator).setRepeatMode(mRepeatMode);
+ }
+ }
mAnimatorSet.setDuration(mDuration);
mAnimatorSet.start();
}
@@ -133,4 +146,13 @@ public AnimatorSet getAnimatorAgent() {
return mAnimatorSet;
}
+ public BaseViewAnimator setRepeatTimes(int repeatTimes) {
+ mRepeatTimes = repeatTimes;
+ return this;
+ }
+
+ public BaseViewAnimator setRepeatMode(int repeatMode) {
+ mRepeatMode = repeatMode;
+ return this;
+ }
}
diff --git a/library/src/main/java/com/daimajia/androidanimations/library/YoYo.java b/library/src/main/java/com/daimajia/androidanimations/library/YoYo.java
index 3c63f4f..d192337 100644
--- a/library/src/main/java/com/daimajia/androidanimations/library/YoYo.java
+++ b/library/src/main/java/com/daimajia/androidanimations/library/YoYo.java
@@ -26,6 +26,8 @@
package com.daimajia.androidanimations.library;
import android.animation.Animator;
+import android.animation.ValueAnimator;
+import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.animation.Interpolator;
@@ -37,11 +39,17 @@ public class YoYo {
private static final long DURATION = BaseViewAnimator.DURATION;
private static final long NO_DELAY = 0;
+ public static final int INFINITE = -1;
+ public static final float CENTER_PIVOT = Float.MAX_VALUE;
private BaseViewAnimator animator;
private long duration;
private long delay;
+ private boolean repeat;
+ private int repeatTimes;
+ private int repeatMode;
private Interpolator interpolator;
+ private float pivotX, pivotY;
private List callbacks;
private View target;
@@ -49,7 +57,12 @@ private YoYo(AnimationComposer animationComposer) {
animator = animationComposer.animator;
duration = animationComposer.duration;
delay = animationComposer.delay;
+ repeat = animationComposer.repeat;
+ repeatTimes = animationComposer.repeatTimes;
+ repeatMode = animationComposer.repeatMode;
interpolator = animationComposer.interpolator;
+ pivotX = animationComposer.pivotX;
+ pivotY = animationComposer.pivotY;
callbacks = animationComposer.callbacks;
target = animationComposer.target;
}
@@ -90,7 +103,12 @@ public static final class AnimationComposer {
private BaseViewAnimator animator;
private long duration = DURATION;
+
private long delay = NO_DELAY;
+ private boolean repeat = false;
+ private int repeatTimes = 0;
+ private int repeatMode = ValueAnimator.RESTART;
+ private float pivotX = YoYo.CENTER_PIVOT, pivotY = YoYo.CENTER_PIVOT;
private Interpolator interpolator;
private View target;
@@ -117,6 +135,35 @@ public AnimationComposer interpolate(Interpolator interpolator) {
return this;
}
+ public AnimationComposer pivot(float pivotX, float pivotY) {
+ this.pivotX = pivotX;
+ this.pivotY = pivotY;
+ return this;
+ }
+
+ public AnimationComposer pivotX(float pivotX) {
+ this.pivotX = pivotX;
+ return this;
+ }
+
+ public AnimationComposer pivotY(float pivotY) {
+ this.pivotY = pivotY;
+ return this;
+ }
+
+ public AnimationComposer repeat(int times) {
+ if (times < INFINITE) {
+ throw new RuntimeException("Can not be less than -1, -1 is infinite loop");
+ }
+ repeat = times != 0;
+ repeatTimes = times;
+ return this;
+ }
+
+ public AnimationComposer repeatMode(int mode) {
+ repeatMode = mode;
+ return this;
+ }
public AnimationComposer withListener(Animator.AnimatorListener listener) {
callbacks.add(listener);
@@ -191,18 +238,35 @@ public boolean isRunning() {
return animator.isRunning();
}
+ public void stop() {
+ stop(true);
+ }
+
public void stop(boolean reset) {
animator.cancel();
if (reset)
animator.reset(target);
}
-
}
private BaseViewAnimator play() {
animator.setTarget(target);
+
+ if (pivotX == YoYo.CENTER_PIVOT) {
+ ViewCompat.setPivotX(target, target.getMeasuredWidth() / 2.0f);
+ } else {
+ target.setPivotX(pivotX);
+ }
+ if (pivotY == YoYo.CENTER_PIVOT) {
+ ViewCompat.setPivotY(target, target.getMeasuredHeight() / 2.0f);
+ } else {
+ target.setPivotY(pivotY);
+ }
+
animator.setDuration(duration)
+ .setRepeatTimes(repeatTimes)
+ .setRepeatMode(repeatMode)
.setInterpolator(interpolator)
.setStartDelay(delay);
@@ -211,7 +275,6 @@ private BaseViewAnimator play() {
animator.addAnimatorListener(callback);
}
}
-
animator.animate();
return animator;
}