I have two TranslateAnimations on a TextView and I want them to execute one after other. However, by using the code below, only the second one is executed.
How can I solve this?
TranslateAnimation animation = new TranslateAnimation(
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, -150.0f);
animation.setDuration(200);
wave.startAnimation(animation);
TranslateAnimation animation1 = new TranslateAnimation(
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 150.0f, Animation.ABSOLUTE, 0.0f);
animation1.setDuration(200);
wave.startAnimation(animation1);
Link them together with
Animation Set
AnimationSet as = new AnimationSet(true)
TranslateAnimation animation = new TranslateAnimation(
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, -150.0f);
animation.setDuration(200);
as.addAnimation(animation);
TranslateAnimation animation1 = new TranslateAnimation(
Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
Animation.ABSOLUTE, 150.0f, Animation.ABSOLUTE, 0.0f);
animation1.setDuration(200);
animation1.setStartOffset(200);
as.addAnimation(animation1);
wave.startAnimation(as);
EDIT: Andy Boots answer below is the better answer imo.
Just set your first one like this and it'll start the other one, once the animation finishes:
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationEnd(Animation animation) {
wave.startAnimation(animation1);
}
});
edit: The reason only your second animation is executed with your current code, is because it overrides the playing of the first animation (both actually are played, but you only see the latest one to start). If you do like I wrote, they will play sequentially instead of in parallel.
also you can do this by XML itself using android:startOffset attribute , and there is an examble:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="300"
android:fromXScale="0%"
android:fromYScale="0%"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="100%"
android:toYScale="100%" />
<alpha
android:duration="300"
android:fromAlpha="0"
android:toAlpha=".5" />
<alpha
android:duration="300"
android:fromAlpha=".5"
android:startOffset="300"
android:toAlpha="1" />
</set>
There is one more approach to reach this goal which can be useful when you need to animate a lot of views one after another. You can use setStartOffset method to set a delay before animation begins. So, if you know, how much time will take for your first animation to end, you can set this as a delay for your second animation. This is an example where I animated six ImageButtons and six TextViews below them one after another:
public void animateButtons() {
// An array of buttons
int[] imageButtonIds = {R.id.searchButton, R.id.favoriteButton, R.id.responseButton, R.id.articleButton, R.id.resumeButton, R.id.subscribeButton};
// Array of textViews
int[] textViewIds = {R.id.searchTextView, R.id.favoriteTextView, R.id.responseTextView, R.id.articleTextView, R.id.resumeTextView, R.id.subscribeTextView};
int i = 1;
for (int viewId : imageButtonIds) {
ImageButton imageButton = (ImageButton) findViewById(viewId);
// Animation from a file fade.xml in folder res/anim
Animation fadeAnimation = AnimationUtils.loadAnimation(this, R.anim.fade);
// Delay for each animation is 100 ms bigger than for previous one
fadeAnimation.setStartOffset(i * 100);
imageButton.startAnimation(fadeAnimation);
// The same animation is for textViews
int textViewId = textViewIds[i-1];
TextView textView = (TextView) findViewById(textViewId);
textView.startAnimation(fadeAnimation);
i ++;
}
}
In my res/anim folder I have a file, called fade.xml with these contents:
<?xml version="1.0" encoding="utf-8"?>
<!-- Fade animation with 500 ms duration -->
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="500" />
Create an animation array and use method for creating AnimationSet.
Animation[] animations = {
getScaleAnimation(0.4f, 1.3f, 2000),
getScaleAnimation(1.3f, 1.0f, 500),
getScaleAnimation(0.4f, 1.3f, 1000),
getScaleAnimation(1.3f, 1.0f, 3000),
getScaleAnimation(0.4f, 1.3f, 500),
getScaleAnimation(1.3f, 1.0f, 1700),
getScaleAnimation(0.4f, 1.3f, 2100),
getScaleAnimation(1.3f, 1.0f, 3400)
};
AnimationSet animationSet = addAnimationAr(animations);
view.startAnimation(animationSet);
Method:
public static AnimationSet addAnimationAr(Animation[] animations) {
AnimationSet animationSet = new AnimationSet(false);
long totalAnimationDuration = 0;
for (int i = 0; i < animations.length; i++) {
Animation a = animations[i];
a.setStartOffset(totalAnimationDuration);
totalAnimationDuration += a.getDuration();
animationSet.addAnimation(a);
}
return animationSet;
}
If you use code, you can call
Animation.setStartOffset()
to delay the second animation.
if you use xml you can android:ordering="sequentially" property to make the two animations perform sequentially.
For simple animations, you can achieve this by using the animate() and withEndAction() functions, like so:
ImageView img = findViewById(R.id.imageView);
img.animate().rotation(180).alpha(0).setDuration(3000).withEndAction(new Runnable() {
#Override
public void run() {
ImageView img = findViewById(R.id.imageView);
img.animate().rotation(0).alpha(1).setDuration(2000);
}
});
AnimationDrawable
Running such animation is pretty straightforward in Android. In fact, there is a class in Android API just for this specific task called AnimationDrwable. AnimationDrawable is a set of images together.
Step1: Create AnimationDrwable
Step2: Load Animation Drawable into ImageView
step3: start the animation
Step 1:
Create an XML and add all images like this.
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="#drawable/cat_image_1" android:duration="200" />
<item android:drawable="#drawable/cat_image_2" android:duration="200" />
<item android:drawable="#drawable/cat_image_3" android:duration="200" />
</animation-list>
Step 2:
public void onCreate(Bundle savedInstanceState) {
//Step 2
ImageView myimage = (ImageView) findViewById(R.id.my_image);
myimage.setBackgroundResource(R.drawable.rocket_thrust);
//Step 3
AnimationDrawable catAnimation = (AnimationDrawable) rocketImage.getBackground();
catAnimation.start();
}
Related
On touch apple "falls" (translates) down from a tree and should rotate around itself and translate.
Animation apple3_anim = AnimationUtils.loadAnimation(this,
R.anim.apple3_animation);
apple3.startAnimation(apple3_anim);
RotateAnimation r = new RotateAnimation(0.0f,
720.0f, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
r.setDuration(2000);
apple3.startAnimation(r);
the xml code for apple3_animation.xml file:
<?xml version="1.0" encoding="utf-8"?>
<translate
android:fromXDelta="0"
android:toXDelta="0"
android:fromYDelta="0"
android:toYDelta="450"
android:duration="1200"
>
</translate>
The issue is that the animations don't happen sequentially,only the last 'r' animation gets executed - the apple rotates around itself 720degrees.
How do I make it go sequentially? even if i put all things in xml file, in the xml , only the last animation gets executed!
using animator can solve it quikely
apple3.animate().translationY(450).setDuration(1200).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
iv.animate().rotation(720).setDuration(2000);
}
}).start();
I have an application where i spawn a new enemy every 4 seconds. the enemy goes from right to left using anTranslateAnimation. This animation takes 7 seconds total.
The problem that I'm facing now is that when the animation is running, every time that i spawn a new enemy, the animation stops for the old one and starts animating the new enemy.
Is there any way to animate two different objects using the same TranslateAnimation?
Just in case, here is my animation
translate= new TranslateAnimation(
Animation.ABSOLUTE, (float) 1.0,
Animation.ABSOLUTE, (float) -4.0,
Animation.ABSOLUTE,0,
Animation.ABSOLUTE,0);
translate.setDuration(10000);
translate.setFillAfter(true);
//newIV is the enemy's ImageView
newIV.startAnimation(translate);
You can apply animation like this
make an animation xml in anim folder
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="500"
/>
</set>
Then code in class
final Animation RightToLeft = AnimationUtils.loadAnimation(context,
R.anim.right_to_left);
((ImageView)findViewById(R.id.yourImage))
.startAnimation(RightToLeft);
Hope it will help.
You can set a same animation to Different views in same position.try to use animationLisener
translate.setAnimationListener(new TranslateAnimation.AnimationListener() { #Override
public void onAnimationStart(Animation animation) { }
#Override
public void onAnimationRepeat(Animation animation) { }
#Override
public void onAnimationEnd(Animation animation)
{
animation.setFillAfter(false);
RelativeLayout.LayoutParams params =(RelativeLayout.LayoutParams)mLogo.getLayoutParams();
//Set your firest view layout or hide the previous newIV
//This ll avoid filckering
animation = new TranslateAnimation(0.0f, 0.0f, 0.0f, 0.0f);
animation.setDuration(1);
ImageView mLogo = new ImageView(activity);// Second enemy as u said
animation = new TranslateAnimation(
Animation.ABSOLUTE, (float) 1.0,
Animation.ABSOLUTE, (float) -4.0,
Animation.ABSOLUTE,0,
Animation.ABSOLUTE,0);
mLogo.startAnimation(animation);mLogo.setLayoutParams(params);
mLogo.clearAnimation();
mLogo.startAnimation(animation);
}
});
This ll animate When first enemy going to end create a new instance of animation and use.
Im trying to do an alpha and translate in a RelativeLayout. I define both:
AlphaAnimation alpha;
alpha = new AlphaAnimation(0.0f, 1.0f);
alpha.setDuration(1500);
alpha.setFillAfter(true);
TranslateAnimation translate;
translate = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 1,
Animation.RELATIVE_TO_SELF, 0);
translate.setDuration(1000);
So I start the animation in my RelativeLayout
RelativeLayout.startAnimation(translate);
RelativeLayout.startAnimation(alpha);
The problem is that in this case, only the alpha animation start and not the translation. Can someone help me? The question is how can I start two different animations at the same time in the same object(Relative Layout in my case)
I resolve the question. I added it:
AnimationSet animationSet = new AnimationSet(true);
animationSet.addAnimation(alpha);
animationSet.addAnimation(translate);
RelativeLayout.startAnimation(animationSet);
You can use animation set ıf you want to run two animation in the same time:
http://developer.android.com/reference/android/view/animation/AnimationSet.html
For exeample;
as = new AnimationSet(true);
as.setFillEnabled(true);
as.setInterpolator(new BounceInterpolator());
TranslateAnimation ta = new TranslateAnimation(-300, 100, 0, 0);
ta.setDuration(2000);
as.addAnimation(ta);
TranslateAnimation ta2 = new TranslateAnimation(100, 0, 0, 0);
ta2.setDuration(2000);
ta2.setStartOffset(2000); // allowing 2000 milliseconds for ta to finish
as.addAnimation(ta2);
Your current code won't work, because as soon as the first animation starts, the second one ends it and starts itself. So you need to wait till it's done.
Try this :
translate.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
RelativeLayout.startAnimation(alpha);
}
});
If you want to execute them simultaneously, I'd suggest you create an animation.xml file in your res/anim/ folder.
Example:
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale=".75"
android:toYScale=".75"
android:duration="1500"/>
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:duration="1500"
android:pivotX="50%"
android:pivotY="50%" />
<scale
android:fromXScale=".75"
android:fromYScale=".75"
android:toXScale="1"
android:toYScale="1"
android:duration="1500"/>
</set>
Java Code:
Animation multiAnim = AnimationUtils.loadAnimation(this, R.anim.animation);
RelativeLayout.startAnimation(multiAnim);
I want to be able to do a text animation and change the size of the text in a TextView. I read that there are property animations in android but if someone knows a simple code that can do this for me or an example somewhere I will deeply appreciate it. Thank u in advance!
scale.xml
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="2.0"
android:toYScale="2.0"
android:duration="3000"></scale>
</set>
A function into an Activity:
private void RunAnimation()
{
Animation a = AnimationUtils.loadAnimation(this, R.anim.scale);
a.reset();
TextView tv = (TextView) findViewById(R.id.firstTextView);
tv.clearAnimation();
tv.startAnimation(a);
}
extracted and modified from here
Animation animation=new TranslateAnimation(0,480,0,0);
animation.setDuration(5000);
animation.setRepeatMode(Animation.RESTART);
animation.setRepeatCount(Animation.INFINITE);
text.startAnimation(animation);
// applying animation to textview object..
If you are using button event to show animation then put the code inside onClick() otherwise use override method onWindowFocusChanged(boolean hasFocus) to start animation
Use ValueAnimator class in the android
final float startSize = o; // Size in pixels
final float endSize = 30;
final int animationDuration = 1000; // Animation duration in ms
ValueAnimator animator = ValueAnimator.ofFloat(startSize, endSize);
animator.setDuration(animationDuration);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float animatedValue = (float) valueAnimator.getAnimatedValue();
tv.setTextSize(animatedValue);
}
});
animator.start();
refer this link ValueAnimator
Another solution is that apply scale animation on Textview or its parent layout
ScaleAnimation scaleAnimation = new ScaleAnimation(0.7f, 1.1f, 0.7f, 1.1f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(600);
viewZoom.startAnimation(scaleAnimation);
I'm developing a gallery app, in this app I'm displaying images in slideshow using gallery. It's working fine, but I want to add some animation. I can apply only one animation with this code but I want to add two animation effects in gallery view.
Say in translation effect, right-to-center and center-to-left. Please anyone help me out.
public void slidShow(){
Runnable runnable = new Runnable() {
#Override
public void run() {
myslideshow();
handler.postDelayed(this, 3000);
}
};
new Thread(runnable).start();
}
private void myslideshow(){
PicPosition = gallery.getSelectedItemPosition() +1;
if (PicPosition >= bitmaps.size()){
PicPosition = gallery.getSelectedItemPosition(); //stop
}
else{
Animation inFromRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, +1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
inFromRight.setDuration(500);
inFromRight.setInterpolator(new AccelerateInterpolator());
gallery.startAnimation(inFromRight);
gallery.setSelection(PicPosition);
}
}
Use Xml based animation
Create a Xml file in folder res/anim/animate.xml
put the code
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="true">
<translate
android:fromXDelta="0%p" android:toXDelta="50%p" // change this to decide the range
android:duration="500" android:startOffset="0"/>
<translate
android:fromXDelta="0%p" android:toXDelta="100%p"
android:duration="500" android:startOffset="500"/>// change this to increase the
time for image to stay
</set>
now in your function myslideshow() change
Animation inFromRight = AnimationUtils.loadAnimation(this, R.anim.animate);
gallery.startAnimation(inFromRight);
gallery.setSelection(PicPosition);
Thats all.....