Android animation does not repeat - android

I'm trying to make simple animation that would repeat several times (or infinitely).
It seems that android:repeatCount does not work!
Here is my animation resource from /res/anim/first_animation.xml :
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false"
android:repeatCount="infinite"
>
<scale
android:interpolator="#android:anim/decelerate_interpolator"
android:duration="500"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="1.2"
android:toYScale="1.2"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false" />
<scale
android:interpolator="#android:anim/accelerate_interpolator"
android:startOffset="500"
android:duration="500"
android:fromXScale="1.2"
android:fromYScale="1.2"
android:toXScale="1.0"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false" />
</set>
First it should scale image from 1.0 to 1.2 size in 500 ms.
And then scale it back to 1.0 in 500 ms.
Here is how I'm using it:
Animation firstAnimation = AnimationUtils.loadAnimation(this, R.anim.first_animation);
imgView.startAnimation(firstAnimation);
It makes one cycle and then finishes.
It scales up, then scales down ans then stops.
How can I make this work as intended?

Update: Back in Sep, 2011 an Android engineer fixed this issue for the most part. The attributes that were ignored in XML now work, with the exception of repeatCount and fillEnabled which are still ignored (on purpose for some reason). This means it still isn't easy to repeat an AnimationSet unfortunately.
For details please see the overview in the updated docs (explains which attributes are ignored, which work, and which are passed onto children). And for a deeper understanding of what fillAfter, fillBefore, and fillEnabled actually do, see the engineer's (Chet Haase) blog post about it here.
Original Answer
To expand upon answers by Pavel and others: it is true that the <set> tag is ridiculously buggy. It can't deal correctly with repeatCount and a number of other attributes.
I spent a few hours figuring out what it can and can't deal with and have submitted a bug report/issue here: Issue 17662
In summary (this concerns AnimationSets):
setRepeatCount() / android:repeatCount
This attribute (as well as repeatMode) does not work in code or XML. This makes repeating an entire set of animations difficult.
setDuration() / android:duration
Setting this on an AnimationSet in code WORKS (overrides all durations of children animations), but not when included in the tag in XML
setFillAfter() / android:fillAfter
This works in both code and XML for the tag. Strangely I have gotten it to also work without the need to set fillEnabled to true.
setFillBefore() / android:fillBefore
Seems to have no effect/ignored in both code and XML
setFillEnabled() / android:fillEnabled
Seems to have no effect/ignored in both code and XML. I can still get fillAfter to work even without including fillEnabled or setting fillEnabled to false.
setStartOffset() / android:startOffset
This works only in code and not XML.

I've found that <set> tag has buggy implementation in class AnimationSet.
It can't deal correctly with repeatCount.
What we can do - is to set repeatCount directly in <scale> tag.
This XML resource is working well:
<?xml version="1.0" encoding="utf-8"?>
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:duration="200"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="1.05"
android:toYScale="1.05"
android:pivotX="50%"
android:pivotY="50%"
android:repeatMode="reverse"
android:fillAfter="false"
android:repeatCount="24"
/>
Unfortunately, this is limited to only one animation at once.
We can not define a sequence of animations this way...

You should include the attribute
android:repeatCount="infinite"
But in your "scale" animation not in "set"

To get a repeating animation I utilized the animation listener, and called the animation again when it ended. This does a camera reticule focusing like animation with brackets.
Here is the animation layout xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0"
android:toXScale=".7"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toYScale=".7"
android:duration="1000"/>
<scale
android:duration="1000"
android:fromXScale=".7"
android:toXScale="1.0"
android:fromYScale=".7"
android:pivotX="50%"
android:pivotY="50%"
android:toYScale="1.0"
android:startOffset="1000"/>
</set>
Here is the java code
public void startAnimation() {
View brackets = findViewById(R.id.brackets);
brackets.setVisibility(View.VISIBLE);
Animation anim = AnimationUtils.loadAnimation(BuzzFinderActivity.this, R.anim.crosshair_focusing);
anim.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation arg0) {
Animation anim = AnimationUtils.loadAnimation(BuzzFinderActivity.this, R.anim.crosshair_focusing);
anim.setAnimationListener(this);
brackets.startAnimation(anim);
}
#Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation arg0) {
// TODO Auto-generated method stub
}
});
brackets.startAnimation(anim);
}

I was also facing the same problem..
i included android:repeatCount="infinite" in XMl file..now its working fine...
<translate
android:fromXDelta="0"
android:toXDelta="80"
android:duration="1000"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="true"/>

you can try this code.
In your code just add,
firstAnimation.setRepeatCount(5);
This will repeat the animation for a definite time
firstAnimation.setRepeatCount(Animation.INFINITE);
firstAnimation.setRepeatMode(Animation.INFINITE);
This will repeat the animation indefinitely.

I tried to use Daniel's code to show animation exact number of times and had a problem: animation was shown approximatily n / 2 times, when n times expected.
So I have modified Daniel's code:
//...
#Override
public void onAnimationEnd(Animation arg0) {
mCurrentCount++;
if (mCurrentCount < REPEAT_COUNT) {
Animation anim = AnimationUtils.loadAnimation(BuzzFinderActivity.this, R.anim.crosshair_focusing);
anim.setAnimationListener(this);
brackets.post(new Runnable() {
#Override
public void run() {
brackets.startAnimation(anim);
}
}
}
}
//...
Using variant, shown above, animation is shown exectly REPEAT_COUNT times, because View.post() method gives an ability to start new animation after finishing all actions, related with previous animation.

you have to add just one line in your xml code that i suggested below .
<scale
android:duration="500"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="1.2"
android:toYScale="1.2"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite" // just add this one line
android:fillAfter="false"
/>
</set>

I solved this problem using android:repeatMode="reverse" before in my project.
<scale
android:interpolator="#android:anim/decelerate_interpolator"
android:duration="500"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="1.2"
android:toYScale="1.2"
android:pivotX="50%"
android:pivotY="50%"
android:repeatMode="reverse"
android:repeatCount="infinite" />

With android sdk version 4.0.3:
In the given animation elements:
android:repeatCount="-1"
makes it an infinite animation.

Add the following class to your project:
import android.view.View;
import android.view.animation.Animation;
public class AnimationRepeater implements Animation.AnimationListener
{
private View view;
private Animation animation;
private int count;
public AnimationRepeater(View view, Animation animation)
{
this.view = view;
this.animation = animation;
this.count = -1;
}
public AnimationRepeater(View view, Animation animation, int count)
{
this.view = view;
this.animation = animation;
this.count = count;
}
public void start()
{
this.view.startAnimation(this.animation);
this.animation.setAnimationListener(this);
}
#Override
public void onAnimationStart(Animation animation) { }
#Override
public void onAnimationEnd(Animation animation)
{
if (this.count == -1)
this.view.startAnimation(animation);
else
{
if (count - 1 >= 0)
{
this.animation.start();
count --;
}
}
}
#Override
public void onAnimationRepeat(Animation animation) { }
}
For infinite loop of your view, do the following:
Animation a = AnimationUtils(Context, R.anim.animation);
new AnimationRepeater(View, a).start();
If you want to repeat the animation for N-times only, do the following:
Animation a = AnimationUtils(Context, R.anim.animation);
new AnimationRepeater(View, a, int N).start();
N stands for number of repetitions.

I do most of my stuff programmatically and I may be late or inefficient on this one but this but I completed the repeat animationset goal (I a even have 2 alternating animation sets). All this code does is simply fade in one image,pause, then fade out, fade in another image, pause, fade out, and bring back the first one (rinse and repeat). I first defined my Imageviews:
final ImageView purple = (ImageView)findViewById(R.id.purp);
final ImageView yellow = (ImageView)findViewById(R.id.yell);
purple.setVisibility(View.INVISIBLE);
yellow.setVisibility(View.INVISIBLE);
Then I made two timers, task timers and handlers to deal with when to start and stop each animation:
Timer p = new Timer();
TimerTask pu = new TimerTask() {
public void run() {
handler1.post(new Runnable() {
public void run()
{
fadein(purple);
}
});
}};
p.schedule(pu, 6000, 12000);
final Handler handler2 = new Handler();
Timer y = new Timer();
TimerTask ye = new TimerTask() {
public void run() {
handler2.post(new Runnable() {
public void run()
{
fadein(yellow);
}
});
}};
y.schedule(ye, 0, 12000);
Finally, rather than creating animation sets by adding animations, I just animations listeners to to determine when to start each animation:
public void fadein (final ImageView image)
{
Animation anim = new AlphaAnimation(0, 1);
anim.setDuration(2000);
image.startAnimation(anim);
anim.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation)
{
image.clearAnimation();
image.invalidate();
pause(image);
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
});
}
public void pause (final ImageView image)
{
Animation anim = new AlphaAnimation(1, 1);
anim.setDuration(2000);
image.startAnimation(anim);
anim.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation)
{
image.clearAnimation();
image.invalidate();
fadeout(image);
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
});
}
public void fadeout (final ImageView image)
{
Animation anim = new AlphaAnimation(1,0);
anim.setDuration(2000);
image.startAnimation(anim);
anim.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation)
{
image.clearAnimation();
image.invalidate();
}
#Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
#Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
});
}
The clearanimation and invalidate where just previous attempts and getting this thing to work right. I don't know if they are required or not.
Hope this helps someone.
Ryan

i got this to go ...i was trying to get a view to rotate in a circle continuously .
previous i was using rotation.setRepeatMode(-1) but that didn't work. switched to setrepeatcount and it works. This is on jelly bean 4.2.2
ObjectAnimator rotation = ObjectAnimator.ofFloat(myview,
"rotation", 360).setDuration(2000);
rotation.setRepeatMode(-1);
rotation.setRepeatCount(Animation.INFINITE);
rotation.start();

I've faced the same problem, but didn't want to do any timing things in Java because of the point that the UI thread may be very busy sometimes.
The INFINITE flag doesn't work for the set tag. So I resolved the issue with a little piece of code:
mAnimation = (AnimationSet) AnimationUtils.loadAnimation(myContext, R.anim.blink);
mIcon.startAnimation(mAnimation);
mAnimation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {}
public void onAnimationRepeat(Animation animation) {}
public void onAnimationEnd(Animation animation) {
mIcon.startAnimation(mAnimation);
}
});
with the following XML:
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromAlpha="0.9"
android:startOffset="1000"
android:toAlpha="0.0" />
Where mIcon is an ImageView from my layout.

I've solved this problem. This is my version of the fix:
public class HelloAndroidActivity extends Activity {
private static String TAG = "animTest";
private Animation scaleAnimation;
private int currentCover = 0;
private List<ImageView> imageViews = new ArrayList<ImageView>(3);
private Button btn;
private ImageView img;
/**
* Called when the activity is first created.
* #param savedInstanceState If the activity is being re-initialized after
* previously being shut down then this Bundle contains the data it most
* recently supplied in onSaveInstanceState(Bundle). <b>Note: Otherwise it is null.</b>
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate");
setContentView(R.layout.test);
img = (ImageView)findViewById(R.id.testpict);
imageViews.add(img);
img = (ImageView)findViewById(R.id.testpictTwo);
imageViews.add(img);
img = (ImageView)findViewById(R.id.testpict3);
imageViews.add(img);
scaleAnimation = AnimationUtils.loadAnimation(this, R.anim.photo_scale);
scaleAnimation.setAnimationListener(new CyclicAnimationListener());
btn = (Button)findViewById(R.id.startBtn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imageViews.get(0).startAnimation(scaleAnimation);
}
});
}
private class CyclicAnimationListener implements AnimationListener{
#Override
public void onAnimationEnd(Animation animation) {
currentCover += 1;
if(currentCover >= imageViews.size()){
currentCover = 0;
}
img = imageViews.get(currentCover);
scaleAnimation = AnimationUtils.loadAnimation(HelloAndroidActivity.this, R.anim.photo_scale);
scaleAnimation.setAnimationListener(new CyclicAnimationListener());
img.startAnimation(scaleAnimation);
}
#Override
public void onAnimationRepeat(Animation animation) {
Log.d("Animation", "Repeat");
}
#Override
public void onAnimationStart(Animation animation) {
}
}
}

i just came across this issue while working on a backwards compatible app. so frustrating! i ended up coding a nice workaround class that can be called from onCreate and will kickoff any animation resource into an indefinite loop.
the class, AnimationLooper, is available here:
https://gist.github.com/2018678

After researching through the answers from internet, I found a solutions which works perfectly for me. (And yes, the repeatCount and repeatMode is extremely buggy when used together with animationSet).
anim_rotate_fade.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:ordering="together" >
<objectAnimator
android:duration="3000"
android:propertyName="rotation"
android:repeatCount="1"
android:valueTo="360"
android:valueType="floatType" />
<objectAnimator
android:duration="3000"
android:propertyName="alpha"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="0.0"
android:valueTo="0.3"
android:valueType="floatType" />
<objectAnimator
android:duration="3000"
android:propertyName="y"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="380"
android:valueTo="430"
android:valueType="floatType" />
</set>
In activity:
(Solve it by introducing a slight delay after animation ended).
ImageView starlightImageView = new ImageView(this);
starlightImageView.setImageResource(R.drawable.starlight);
final AnimatorSet animate = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.anim.anim_rotate_fade);
AnimatorListenerAdapter animatorListener = new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
new Handler().postDelayed(new Runnable() {
#Override public void run() {
animate.start();
}
}, 1000);
}
};
animate.setTarget(starlightImageView);
animate.addListener(animatorListener);
There are a lot of classes you would like to research on, but currently I'm using objectAnimator which is highly flexible. I wouldn't recommend to use Animation or AnimationUtils:
Animation
AnimationUtils
Animator
AnimatorInflater
AnimatorListener
AnimatorListenerAdapter

One need to listen for completion of first animation then re-start the animation in onStopAnimation call back, give a try to this link

Little tweak to #Danufr answer to save resources from loading again.
operator = (ImageView) findViewById(R.id.operator_loading);
final Animation ani = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.finding_operator);
ani.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
operator.startAnimation(ani);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
operator.setAnimation(ani);

I solved this problem using thread.
Button btn = (Button) findViewById(R.id.buttonpush);
final TextView textview = (TextView) findViewById(R.id.hello);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
textview.setText("...................");
final Animation animationtest = AnimationUtils.loadAnimation(MainActivity.this, android.R.anim.slide_in_left);
animationtest.setDuration(1000);
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
handler.postDelayed(this, 1500);
textview.startAnimation(animationtest);
}
};
handler.postDelayed(runnable, 500); // start
handler.removeCallbacks(runnable); //STOP Timer
}
});

it's working fine
GifDrawable gifDrawable = (GifDrawable) gifImageView.getDrawable();
gifDrawable.setLoopCount(0);

None of the above solutions worked in my case. The solution by Danuofr did work for animation set but when I was doing unit testing, my tests used to get stuck in this infinite loop. Finally, specific to my case, I needed to repeat this animation specific number of times. So, I manually added copies of my animation in anim_rot.xml in a cascaded manner adding the offset value. I know it's bad and won't work for many but it was the only workaround for my case.
anim_rot.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="2000"
android:fromDegrees="20"
android:pivotX="29%"
android:pivotY="50%"
android:toDegrees="-20" />
<rotate
android:duration="2000"
android:fromDegrees="-20"
android:pivotX="29%"
android:pivotY="53%"
android:startOffset="2000"
android:toDegrees="20" />
<rotate
android:startOffset="4000"
android:duration="2000"
android:fromDegrees="20"
android:pivotX="29%"
android:pivotY="56%"
android:toDegrees="-20" />
<rotate
android:duration="2000"
android:fromDegrees="-20"
android:pivotX="29%"
android:pivotY="59%"
android:startOffset="6000"
android:toDegrees="20" />
<rotate
android:startOffset="8000"
android:duration="2000"
android:fromDegrees="20"
android:pivotX="29%"
android:pivotY="62%"
android:toDegrees="-20" />
<rotate
android:duration="2000"
android:fromDegrees="-20"
android:pivotX="29%"
android:pivotY="65%"
android:startOffset="10000"
android:toDegrees="20" />
</set>
I did this to repeat the animation 3 times. You can add more copies to repeat it specific times by adding offset values.

Try to add the code to a looping thread or a while/for statement

Related

How to only dismiss a popupWindow after animation end

I know that exist a topic similar with this Question but I cant figure how to make this work with my code.
I have one popupwindow, (I dont even know if this is the best way to do what I want but Im new on Android), but I have done a popupWindow appear on click of a image with a animation that I found here, after I read a Question about how to animate the popupwindow and that I have todo the animation of the Enter and the Exit, I figure how to do that, but now my Question:
I dont know how to do the popupwindow dismiss after the Enter Animatio ends.
popupWindow code:
LayoutInflater inflater = (LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
View viewAnimationResourceEarned = inflater.inflate(R.layout.layout_animation_resources_earned, null);
animationResourceEarned = new PopupWindow(viewAnimationResourceEarned, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
animationResourceEarned.setAnimationStyle(R.style.styleAnimationResourceEarned);
animationResourceEarned.showAtLocation(viewAnimationResourceEarned, Gravity.CENTER, 0, 0);
Enter Animation code:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:toXScale="1.0"
android:fromXScale="0.0"
android:toYScale="1.0"
android:fromYScale="0.0"
android:pivotX="0%"
android:pivotY="50%"
android:startOffset="100"
android:duration="300" />
<translate
android:fromYDelta="0"
android:toYDelta="-50"
android:duration="2500"/>
</set>
I want to dismiss the popup window after the Enter Animation end, My objective is the popupappear, move to the top a litle and diseppear
You can use the animation listener.
You have to define the animation in an animation variable like this
Animation animation = AnimationUtils.loadAnimation(this, R.style.styleAnimationResourceEarned);
And then,
animation.setAnimationListener(new Animation.AnimationListener() {
#Override public void onAnimationStart(Animation animation) {
}
#Override public void onAnimationEnd(Animation animation) {
//Dismiss it
}
#Override public void onAnimationRepeat(Animation animation) {
} });
Bruno,
Faced the same issue. Unfortunately there is currently no way to get a callback to animation used in popupwindow. I did a small workaround using countdowntimer.
Not perfect - but works well. Hope it helps.
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
#Override
public void onDismiss() {
new CountDownTimer(animationDuration, 10) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
toggle();
}
}.start();
}
});
Additionally to get the animation duration from resource file use following code
int[] attrs = {android.R.attr.windowExitAnimation};
TypedArray ta = context.obtainStyledAttributes(R.style.PopUpMenuAnimation, attrs);
int resID = ta.getResourceId(0,0);
Animation anim = AnimationUtils.loadAnimation(context, resID);
final long animationDuration = anim.getDuration();

Problems with Views and animations

I have Linear Layouts that i want to replace each other on click.
At start: Linear Layout A is visible, Linear Layout B is gone
I want when A is clicked to be gone and B to be visible and vice versa.
without the animation it all worked just fine, but when i set animation after clicking B B is gone, but A is not visible although if i click in its place the Log gives me that it's visible
here's the code, any help would be appreciated
private void switchRowItems(final LinearLayout toBeHiddenRow,final LinearLayout toBeShownRow){
toBeHiddenRow.animate()
.rotation(toBeHiddenRow.getHeight()/2)
.alpha(0.0f)
.setDuration(300)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
toBeHiddenRow.clearAnimation();
toBeHiddenRow.setVisibility(View.GONE);
toBeShownRow.clearAnimation();
toBeShownRow.setVisibility(View.VISIBLE);
}
});
//toBeShownRow.clearAnimation();
// toBeShownRow.setVisibility(View.VISIBLE);
}
and the on click checker is as simple as:
if (llRowTwoItemOne.getVisibility() == View.VISIBLE) {
Log.d("llRowTwoItemOne","visible");
} else {
Log.d("llRowTwoItemOne","not visible");
}
I do it in this way:
Create xml file in res/anim resource directory. Let's call it myanimation.xml and write there:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:duration="300">
</rotate>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="200">
</alpha>
</set>
You can see that it is a set of animations you need: rotation and alpha.
Then I write in the switchRowItem function this:
private void switchRowItems(final LinearLayout toBeHiddenRow, final LinearLayout toBeShownRow){
Animation anim = AnimationUtils.loadAnimation(this, R.anim.myanimation);
anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
toBeHiddenRow.setVisibility(View.GONE);
toBeShownRow.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
toBeHiddenRow.startAnimation(anim);
}
That's all. It works pretty well. Hope this is what you asked for.

Repeat android animation

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.vitesse);
gpsManager = new GPSManager();
gpsManager.startListening(getApplicationContext());
gpsManager.setGPSCallback(this);
Typeface tf = Typeface.createFromAsset(getAssets(),
"font/DS-DIGI.TTF");
TextView loding =(TextView)findViewById(R.id.info_message);
loding.setTypeface(tf);
AlphaAnimation fadeIn = new AlphaAnimation(0.0f , 1.0f ) ;
AlphaAnimation fadeOut = new AlphaAnimation( 1.0f , 0.0f ) ;
loding.startAnimation(fadeIn);
loding.startAnimation(fadeOut);
fadeIn.setDuration(500);
fadeOut.setDuration(1200);
fadeOut.setStartOffset(1200+fadeIn.getStartOffset()+1200);
measurement_index = AppSettings.getMeasureUnit(this);
}
I want to repeat this of textview loding animation until gotting an inforamtion from GPS
Like this.
animation.setRepeatCount(Animation.INFINITE);
Android gives you elegant mechanisms to represent the loading process. You could use an indeterminate ProgressBar, or an ImageView with a scale/alpha animation, instead of animating the TextView itself.
Maybe you might find this animation useful, for animating alpha and scale at the same time. Vary the parameters for your preference:
file res/anim/alpha_scale_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<scale
android:fromXScale="0.7"
android:toXScale="1.0"
android:fromYScale="0.7"
android:toYScale="1.0"
android:pivotX="50%p"
android:pivotY="50%p"
android:duration="4000"
android:repeatCount="infinite"
/>
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="2000"
android:repeatMode="reverse"
android:repeatCount="infinite"
/>
</set>
then to launch it in your code:
Animation connectingAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.alpha_scale_animation);
myView.startAnimation(connectingAnimation);
And to stop it:
myView.clearAnimation();
connectingAnimation.cancel();
connectingAnimation.reset();
You can also use libraries like ProgressButtonView to have both user interaction and loading process supported in the same widget.
Hope that any of these solutions result useful to someone :)
You can use these methods to control the repeat behavior:
fadeIn.setRepeatCount(int count) // or Animation.INFINITE
fadeIn.setRepeatMode(Animation.REPEAT) // or any other repeat mode, such as Animation.REVERSE
implement these listeners, if needed:
// anim = your animation
anim.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation arg0)
{
// TODO Auto-generated method stub
}
public void onAnimationRepeat(Animation arg0)
{
// TODO Auto-generated method stub
}
public void onAnimationEnd(Animation arg0)
{
// TODO Auto-generated method stub
}
});
if you wanna stop your animation suddenly, use yourView.clearAnimation() I hope this helps.
to repeat animation just add the code in xml file which located in anim folder file in which we create a animation object.
android:repeatCount="infinite"
android:repeatMode="restart"
Set repeat count to -1 then it will animate infinite

android sequential tween animation

Ok.. I got this animation set up for a small imageview for translating from "0%" to "50%" in XML...
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<translate
android:duration="400"
android:fromXDelta="0%"
android:toXDelta="+50%" />
</set>
After this, I need to add another sequential animation which would change the Y co-ordinate from "0%" to "50%".. I tried adding another <set> but it did not work... What should I do to get sequential animation?
You can use android:startOffset to delay animations. Delay in milliseconds before the animation runs, once start time is reached. Must be an integer value, such as "100". -- "developer.android.com"
Another way is you can use AnimationListener to "listen" animations and do whatever you want.
This link is useful for you: How to run several translate animations sequentially?
I'm not completly sure what you really want to do, but if you want to "translate" both the "x" and "y" at the same time simply add android:fromYDelta="0%" and android:toYDelta="+50%" to your existing <translate>.
If you want to "translate" the Y values after the X ones, you will need a new XML file, which you will need to call when the X ones finish.
A quick, untested example:
mAnimatedView = findViewById(R.id.viewToAnimate);
mAnimX = (TranslateAnimation) AnimationUtils.loadAnimation(mContext, R.anim.aX);
mAnimY = (TranslateAnimation) AnimationUtils.loadAnimation(mContext, R.anim.aY);
mAnimX.setAnimationListener(new AnimationListener(){
#Override
public void onAnimationEnd(Animation animation) {
if (mAnimatedView) {
mAnimatedView.startAnimation(mAnimY);
}
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
});
mAnimY.setAnimationListener(new AnimationListener(){
#Override
public void onAnimationEnd(Animation animation) {
if (mAnimatedView) {
mAnimatedView.startAnimation(mAnimX);
}
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
});
mAnimatedView.startAnimation(mAnimX);
Hope that helps and is clear enough.

Android fade in and fade out with ImageView

I'm having some troubles with a slideshow I'm building.
I've created 2 animations in xml for fade in and fade out:
fadein.xml
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="2000"/>
</set>
fadeout.xml
<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:duration="2000"/>
</set>
What Im'trying to do, is to change images from an ImageView using the fade effect, so the currently displayed image will fade out, and another one will fade in.
Considering that I have an image already set, I can fadeout this Image without problem, with this:
Animation fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.your_fade_in_anim);
imageView.startAnimation(fadeoutAnim);
But then, I set the next image to be displayed:
imageView.setImageBitmap(secondImage);
It just shows up in the imageView, and when i set the animation it hides the image, the fade it in... Is there any way to fix that, I mean, when I do imageView.setImageBitmap(secondImage); command, the image do not shows up immediately, and only when the fade in animation is executed?
I wanted to achieve the same goal as you, so I wrote the following method which does exactly that if you pass it an ImageView and a list of references to image drawables.
ImageView demoImage = (ImageView) findViewById(R.id.DemoImage);
int imagesToShow[] = { R.drawable.image1, R.drawable.image2,R.drawable.image3 };
animate(demoImage, imagesToShow, 0,false);
private void animate(final ImageView imageView, final int images[], final int imageIndex, final boolean forever) {
//imageView <-- The View which displays the images
//images[] <-- Holds R references to the images to display
//imageIndex <-- index of the first image to show in images[]
//forever <-- If equals true then after the last image it starts all over again with the first image resulting in an infinite loop. You have been warned.
int fadeInDuration = 500; // Configure time values here
int timeBetween = 3000;
int fadeOutDuration = 1000;
imageView.setVisibility(View.INVISIBLE); //Visible or invisible by default - this will apply when the animation ends
imageView.setImageResource(images[imageIndex]);
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator()); // add this
fadeIn.setDuration(fadeInDuration);
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator()); // and this
fadeOut.setStartOffset(fadeInDuration + timeBetween);
fadeOut.setDuration(fadeOutDuration);
AnimationSet animation = new AnimationSet(false); // change to false
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
animation.setRepeatCount(1);
imageView.setAnimation(animation);
animation.setAnimationListener(new AnimationListener() {
public void onAnimationEnd(Animation animation) {
if (images.length - 1 > imageIndex) {
animate(imageView, images, imageIndex + 1,forever); //Calls itself until it gets to the end of the array
}
else {
if (forever){
animate(imageView, images, 0,forever); //Calls itself to start the animation all over again in a loop if forever = true
}
}
}
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
});
}
To implement this the way you have started, you'll need to add an AnimationListener so that you can detect the beginning and ending of an animation. When onAnimationEnd() for the fade out is called, you can set the visibility of your ImageView object to View.INVISIBLE, switch the images and start your fade in animation - you'll need another AnimationListener here too. When you receive onAnimationEnd() for your fade in animation, set the ImageView to be View.VISIBLE and that should give you the effect you're looking for.
I've implemented a similar effect before, but I used a ViewSwitcher with 2 ImageViews rather than a single ImageView. You can set the "in" and "out" animations for the ViewSwitcher with your fade in and fade out so it can manage the AnimationListener implementation. Then all you need to do is alternate between the 2 ImageViews.
Edit:
To be a bit more useful, here is a quick example of how to use the ViewSwitcher. I have included the full source at https://github.com/aldryd/imageswitcher.
activity_main.xml
<ViewSwitcher
android:id="#+id/switcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:inAnimation="#anim/fade_in"
android:outAnimation="#anim/fade_out" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="#drawable/sunset" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:src="#drawable/clouds" />
</ViewSwitcher>
MainActivity.java
// Let the ViewSwitcher do the animation listening for you
((ViewSwitcher) findViewById(R.id.switcher)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewSwitcher switcher = (ViewSwitcher) v;
if (switcher.getDisplayedChild() == 0) {
switcher.showNext();
} else {
switcher.showPrevious();
}
}
});
Have you thought of using TransitionDrawable instead of custom animations?
https://developer.android.com/reference/android/graphics/drawable/TransitionDrawable.html
One way to achieve what you are looking for is:
// create the transition layers
Drawable[] layers = new Drawable[2];
layers[0] = new BitmapDrawable(getResources(), firstBitmap);
layers[1] = new BitmapDrawable(getResources(), secondBitmap);
TransitionDrawable transitionDrawable = new TransitionDrawable(layers);
imageView.setImageDrawable(transitionDrawable);
transitionDrawable.startTransition(FADE_DURATION);
I used used fadeIn animation to replace new image for old one
ObjectAnimator.ofFloat(imageView, View.ALPHA, 0.2f, 1.0f).setDuration(1000).start();
you can do it by two simple point and change in your code
1.In your xml in anim folder of your project, Set the fade in and fade out duration time not equal
2.In you java class before the start of fade out animation, set second imageView visibility Gone then after fade out animation started set second imageView visibility which you want to fade in visible
fadeout.xml
<alpha
android:duration="4000"
android:fromAlpha="1.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:toAlpha="0.0" />
fadein.xml
<alpha
android:duration="6000"
android:fromAlpha="0.0"
android:interpolator="#android:anim/accelerate_interpolator"
android:toAlpha="1.0" />
In you java class
Animation animFadeOut = AnimationUtils.loadAnimation(this, R.anim.fade_out);
ImageView iv = (ImageView) findViewById(R.id.imageView1);
ImageView iv2 = (ImageView) findViewById(R.id.imageView2);
iv.setVisibility(View.VISIBLE);
iv2.setVisibility(View.GONE);
animFadeOut.reset();
iv.clearAnimation();
iv.startAnimation(animFadeOut);
Animation animFadeIn = AnimationUtils.loadAnimation(this, R.anim.fade_in);
iv2.setVisibility(View.VISIBLE);
animFadeIn.reset();
iv2.clearAnimation();
iv2.startAnimation(animFadeIn);
For infinite Fade In and Out
AlphaAnimation fadeIn=new AlphaAnimation(0,1);
AlphaAnimation fadeOut=new AlphaAnimation(1,0);
final AnimationSet set = new AnimationSet(false);
set.addAnimation(fadeIn);
set.addAnimation(fadeOut);
fadeOut.setStartOffset(2000);
set.setDuration(2000);
imageView.startAnimation(set);
set.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) { }
#Override
public void onAnimationRepeat(Animation animation) { }
#Override
public void onAnimationEnd(Animation animation) {
imageView.startAnimation(set);
}
});
I'm using this kind of routine for programmatically chaining animations.
final Animation anim_out = AnimationUtils.loadAnimation(context, android.R.anim.fade_out);
final Animation anim_in = AnimationUtils.loadAnimation(context, android.R.anim.fade_in);
anim_out.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation)
{
////////////////////////////////////////
// HERE YOU CHANGE YOUR IMAGE CONTENT //
////////////////////////////////////////
//ui_image.setImage...
anim_in.setAnimationListener(new AnimationListener()
{
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {}
});
ui_image.startAnimation(anim_in);
}
});
ui_image.startAnimation(anim_out);
The best and the easiest way, for me was this..
->Simply create a thread with Handler containing sleep().
private ImageView myImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shape_count); myImageView= (ImageView)findViewById(R.id.shape1);
Animation myFadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.fadein);
myImageView.startAnimation(myFadeInAnimation);
new Thread(new Runnable() {
private Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
Log.w("hendler", "recived");
Animation myFadeOutAnimation = AnimationUtils.loadAnimation(getBaseContext(), R.anim.fadeout);
myImageView.startAnimation(myFadeOutAnimation);
myImageView.setVisibility(View.INVISIBLE);
}
};
#Override
public void run() {
try{
Thread.sleep(2000); // your fadein duration
}catch (Exception e){
}
handler.sendEmptyMessage(1);
}
}).start();
}
This is probably the best solution you'll get. Simple and Easy. I learned it on udemy.
Suppose you have two images having image id's id1 and id2 respectively and currently the image view is set as id1 and you want to change it to the other image everytime someone clicks in. So this is the basic code in MainActivity.java File
int clickNum=0;
public void click(View view){
clickNum++;
ImageView a=(ImageView)findViewById(R.id.id1);
ImageView b=(ImageView)findViewById(R.id.id2);
if(clickNum%2==1){
a.animate().alpha(0f).setDuration(2000); //alpha controls the transpiracy
}
else if(clickNum%2==0){
b.animate().alpha(0f).setDuration(2000); //alpha controls the transpiracy
}
}
I hope this will surely help

Categories

Resources