I have an ImageView with alpha=0 by default. So it acts as an invisible overlay on another image.
On click, I want to create an animation that shows the overlay image for 200ms, and then hides it again.
The following does work in general, but only a single time! Why?
final ImageView flash = (ImageView) view.findViewById(R.id.flash);
flash.animate()
.alpha(255) //make visible
.setDuration(200)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
flash.setImageAlpha(0); //hide again
}
});
you're setting 2 different alpha values, the first one is View's alpha, but when you end the animation you set the ImageView class alpha to 0, so if you start the animation again, the View alpha is 1.0f but the image alpha will be 0 and you see nothing.
change it to
flash.animate()
.alpha(1.f)
.setDuration(200)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
flash.setAlpha(0.f);
}
});
View (and therefore ImageView) has a method setAlpha(float), ImageView adds also another method setAlpha(int), which is deprecated because it's confusing as hell and now it's been renamed to setImageAlpha(int). the animation will call View's setAlpha(float)
Related
I placed an ImageView in the centre of the screen. I then wanted to animate it from the bottom to the centre. I reasoned to move it without delay out of the screen and then back the same value which would end in the centre. However, the animation makes it so the view will exit from top.
mLogoIV.animate().translationY(1000f).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mLogoIV.animate().translationY(-1000f).setDuration(3000);
}
});
use translationYBy( to animate relative to the current position
https://developer.android.com/reference/android/view/ViewPropertyAnimator.html#translationYBy(float)
mLogoIV.animate().translationYBy(1000f).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mLogoIV.animate().translationYBy(-1000f).setDuration(3000);
}
});
From the docs:
The amount to be animated by, as an offset from the current value.
vs what you are doing now:
The value to be animated to.
Use Object animator.
ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(mLogoIV, "translationY", -750, 0);
objectAnimator.setDuration(1000);
objectAnimator.start();
In my app I'm using an arrow as a drawable, for which I'd like to animate the fillColor property. I came across AnimatedVectorDrawable examples which modify properties such as pathData, transateY/X, rotation etc., How do I animate the fillColor property, so that my arrow changes color periodically?
The function animate() haven't got a method to change fillColor directly, but you can do a litle trick. In the next code I show you how use the function animate() to simulate the change of fillColor using the function animate twice:
drawableView.animate()
.alpha(0.0f)
.setDuration(100)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
/*
In this point you can change de color of drawable,
the color or property that you want to change (title, color, size...)
*/
drawableView.animate()
.alpha(1.0f)
.setDuration(100)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
}
});
Using code above, you can change some property of drawable inside the animation, I mean, the proccess will be the next:
1 - Animation do that the drawable disappear (alpha 0)
2 - You change the property you want
3 - Animation do that the drawable appear again (alpha 1)
If you use this code inside Timer, you can do that the drawable change the color periodically.
I'm trying to swap two images in separate Imageviews with a fade-out/fade-in. The first image fades out, then the other image fades out, then the second image fades in while replaced with the first image, then the first image fades back in while being replaced with the second image (swap images with fade out/in). The code is below. The swap is occurring okay but there is no fade out or in. What am I missing to get the alpha fade to occur? Also, if I use an integer (such as 1500) instead of mShortAnimationDuration, the animationlistener does not get triggered. setDuration argument is type long. I based my code on the example from here: https://developer.android.com/training/animation/crossfade.html
Drawable target_draw = target.getDrawable();
Drawable dragged_draw = dragged.getDrawable();
final Bitmap targetBitmap = ((BitmapDrawable)target_draw).getBitmap();
final Bitmap draggedBitmap = ((BitmapDrawable)dragged_draw).getBitmap();
//SWAP and CROSSFADE ANIMATION
dragged.setAlpha(1f);
target.setAlpha(1f);
int mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
dragged.animate()
.alpha(0f)
.setDuration(mShortAnimationDuration)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
dragged.setImageBitmap(targetBitmap);
dragged.invalidate();
}
});
target.animate()
.alpha(0f)
.setDuration(mShortAnimationDuration)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
target.setImageBitmap(draggedBitmap);
target.invalidate();
}
});
//fade in with new images
target.animate()
.alpha(1f)
.setDuration(1500);
dragged.animate()
.alpha(1f)
.setDuration(1500);
UPDATE:
I finally came up with the following code which basically works, but due to the fact that Android is not a real-time OS, and that fact that I am swapping images and calling invalidate() during the fade transitions, makes the timing of the fades somewhat unpredictable.
dragged.animate()
.alpha(0f)
.setDuration(1000)
//.setInterpolator(new DecelerateInterpolator()) //optional
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
dragged.setImageBitmap(targetBitmap);
dragged.invalidate();
dragged.animate()
.alpha(1f)
//.setInterpolator(new AccelerateInterpolator())
.setDuration(1000);
//.setStartDelay(500); //also optional for timing
}
});
target.animate()
.alpha(0f)
.setDuration(1000)
.setStartDelay(500)
//.setInterpolator(new DecelerateInterpolator())
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
target.setImageBitmap(draggedBitmap);
target.invalidate();
target.animate()
.alpha(1f)
//.setInterpolator(new AccelerateInterpolator())
//.setStartDelay(500)
.setDuration(1000);
}
});
...update continued:
Since the timing of the fades were inconsistent due to image swapping during them, I simplified and eliminated the fade-out, and just kept the image swap and fade-in. This is the code I ended up with. I am looking for more interesting ways to animate Imageview swapping if anyone has any ideas on that.
// swap
dragged.setImageBitmap(targetBitmap);
dragged.invalidate();
target.setImageBitmap(draggedBitmap);
target.invalidate();
// then fade-in with delay
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
Animation fadeIn2 = new AlphaAnimation(0, 1);
fadeIn2.setInterpolator(new DecelerateInterpolator());
fadeIn2.setStartOffset(300);
fadeIn.setDuration(2000);
fadeIn2.setDuration(2000);
target.startAnimation(fadeIn);
dragged.startAnimation(fadeIn2);
I have an Activity with a toolbar (which is part of the SharedElements Activity entering animation) and below that toolbar are three ImageViews horizontally next to each other. In their XML implementation all three are set INVISIBLE.
What I'm trying to do is, to animate them sequentially "dropping" from behind the toolbar. My implemenation is this:
int delay = 500;
for (int y = 0; y < 3; y++) {
ObjectAnimator oa = ObjectAnimator.ofFloat(imageViews[y],
"translationY", -300, 0);
oa.setDuration(600);
oa.setStartDelay(delay);
oa.start();
imageViews[y].setVisibility(View.VISIBLE);
delay = delay+100;
}
}
As you can see, I'm iterating through the three ImageViews and start a animation for each one to go from a -300 X-position (which is behind the toolbar) to their normal position.
This animation works great - just as I want it to be, but the problem is, that right before all ImageViews are briefly flickering which I can't explain. I tried debugging, but while I'm going through the lines of that part my screen stays black. So I can't determine where/why the Views become visible.
Maybe you can help me to find my mistake.
Thank you, this is my working Code:
For all three ImageViews:
ObjectAnimator anim1Pin = ObjectAnimator.ofFloat(img_pinned, "translationY", -300, 0);
anim1Pin.setDuration(ANIMATON_DURATION);
anim1Pin.setStartDelay(300);
anim1Pin.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
img_pinned.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animator animation) {
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
And the AnimatorSet:
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(anim1Pin, anim2Alarm, anim3LED);
animatorSet.start();
Few things, first, the problem may be as simple as setting the visiblity state to GONE and then after animation starts, setting it to visible. However, I would also use AnimatorSet to play the animations together and add the delay rather than do it in a loop.
If you use AnimatorSet there is an onAnimationStart method in AnimationListener that you can use the set the visible to VISIBLE rather than do it how you have to ensure that they become visible at the right time.
I am trying to do animation with my custom view. This custom view is a combination of other view. I am trying to do a very simple animation and it get triggered when a button is clicked. I want the view to slide and disappear in 2 seconds. But It seems it disappears in less than 2 seconds. I tried to increase the duration but it did not help.
public void hideBar() {
this.setVisibility(View.GONE);
}
private void animateAndHide(){
this.animate()
.translationY(0)
.setDuration(2000)
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
hideBar();
}
});
}
I am not sure what I am doing wrong here.
This happened with me before the view seems to be invisible because the alpha becomes very low before it becomes 0 so try another value like alpha 0.1
Have you tried setStartOffset(2000)? The offset will delay your animation, so if you want to start your animation after a specific time, use the offset method.