I have an imageView that I want to start as invisible. After a certain button is clicked, I want to animate the Image into view and then I want it to remain at alpha 1. How do I do that? So far no luck. If I set the alpha to 0 in xml, then I never see the image. If I don't set alpha in xml then the image is always visible, and when the button is clicked it animates from 0 to 1 alpha.
Here is my animation code.
AlphaAnimation animation1 = new AlphaAnimation(0.0f, 1.0f);
animation1.setDuration(1000);
animation1.setStartOffset(5000);
animation1.setFillAfter(true);
tokenBtn.startAnimation(animation1);
In MainActivity.java add
public void blink(View view) {
ImageView image = (ImageView) findViewById(R.id.imageView);
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.blink);
image.startAnimation(animation1);
}
Create file named blink.xml in res>anim folder and add this code
<?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="--YOUR DURATION--"
android:repeatMode="reverse"
android:repeatCount="0"/>
</set>
And make sure that onClick function on button is named blink
Try to make your ImageView invisible in xml:
<ImageView
...
android:visibility="invisible"/>
Then, by adding an AnimationListener, make it visible in onAnimationStart:
...
animation1.setFillAfter(true);
animation1.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
// pass it visible before starting the animation
tokenBtn.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) { }
#Override
public void onAnimationEnd(Animation animation) { }
});
// finally, start the animation
tokenBtn.startAnimation(animation1);
You can simply set initial alpha to 0 then animate it through 1 with desired duration;
imageView.setAlpha(0);
imageView.animate()
.alpha(1)
.setDuration(200);
Related
I am working on a App that is simple in work and it is working quite efficiently. But I have one place where I am looking something is not looking great and that is flipping Animation.
What I Want :
I have a Button and a ImageView beneath the button. On a Button click I want to make a Animation that it looks like ImageView has flipped and next image is shown in the ImageView. So on every click it should show next image with a flipping animation but there are some problems. I would discuss later but first let me show you how I am doing this.
What I have done so far :
flipping.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0" android:valueTo="180" android:propertyName="rotationY" >
</objectAnimator>
in Activity
#Override
public void onClick(View v) {
flipAnimation();
ivAnimPicture.setImageResource(myImage1);
}
private void flipAnimation(){
ObjectAnimator anim = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.flipping);
anim.setTarget(ivAnimPicture);
anim.setDuration(1500);
anim.start();
}
Problem
When It rotates to 180 from 0 , when it comes exactly at 90 degree we can see image view edges so it makes the animation look not so good. and Also the image changes first then the Flipping animation starts where as I want that Flipping animation should start and in the middle of it the new image should appear. so when the animation stops there should be surprisingly new image for the user.
So I really do not want Image to set in the image-view and then the Animation starts and Animate the image view
Please suggest me more good way or if there is library which is not obsolete.
Chathuranga's solution will do the job. but you better:
1.Use ViewPropertyAnimator. Specially, when you need to perform different animations on several ImageViews.
2.rotate from 270f to 360f for second flip, otherwise your image will be mirrored.
3.Load your second Image into a Drawable before starting the animation, to have a smooth rotation.
final Drawable drawable=getResources().getDrawable(R.drawable.a);
final ImageView iv = ((ImageView)findViewById(R.id.imageView1));
iv.setRotationY(0f);
iv.animate().rotationY(90f).setListener(new AnimatorListenerAdapter()
{
#Override
public void onAnimationEnd(Animator animation)
{
iv.setImageDrawable(drawable);
iv.setRotationY(270f);
iv.animate().rotationY(360f).setListener(null);
}
});
I was in your situation trying to figure out how to get this animation done. Here's how I achieve this.
you need to define two animations. one to rotate from 0 degree to 90 degree and other for to rote from 90 degree to 180 degree
flipstage1.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="rotationY"
android:valueFrom="0"
android:valueTo="90">
</objectAnimator>
flipstage2.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="rotationY"
android:valueFrom="90"
android:valueTo="180">
</objectAnimator>
Place these two files under res/animator
In your code start first animation first, add a listener to it. On animation end change the image and start second animation.
ObjectAnimator animStage1 = (ObjectAnimator) AnimatorInflater.loadAnimator(getActivity(), R.animator.flipstage1);
final ObjectAnimator animStage2 = (ObjectAnimator) AnimatorInflater.loadAnimator(getActivity(), R.animator.flipstage2);
animStage1.setTarget(imageIcon1);
animStage2.setTarget(imageIcon1);
animStage1.setDuration(500);
animStage2.setDuration(500);
animStage1.start();
animStage1.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
animStage2.start();
imageIcon1.setImageDrawable(ResourcesCompat.getDrawable(view.getResources(),R.drawable.okicon,null));
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
imageIcon1 is the reference to image view in xml layout.
Try this simple piece of code and let me know
ObjectAnimator anim = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.flipping);
anim.setTarget(ivAnimPicture);
anim.setDuration(1500);
anim.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
ivAnimPicture.setImageResource(myImage1);
}
});
anim.start();
I'm trying to translate an ImageView, moving it downward one step at a time with each click. However, the animation only works for the first button click; all subsequent clicks only change the ImageView's location without the animation.
Here is my move_down.xml file:
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromYDelta="0%"
android:toYDelta="100%"
android:duration="500"
/>
Here is my button declaration in my main.xml:
<Button
android:id="#+id/bGo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go"
android:onClick="startAnimation" />
Here is my startAnimation function:
public void startAnimation(View view) {
Animation test = AnimationUtils.loadAnimation(this, R.anim.move_down);
character.startAnimation(test);//This is the ImageView I'm trying to animate
test.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {}
public void onAnimationRepeat(Animation animation) {}
public void onAnimationEnd(Animation animation) {
character.setY(character.getY() + character.getHeight());
}
});
}
When I commented out the line
character.setY(character.getY() + character.getHeight());
The animation would work but the location of the ImageView would snap back after the animation was finished.
take out
character.setY(character.getY() + character.getHeight());
Use the fillAfter attribute of the Animation to make it stay where it is at when the animation ends.
Like this:
Animation test = AnimationUtils.loadAnimation(this, R.anim.move_down);
test.setFillAfter(true);
Maybe you should try something like this
public void startAnimation(View view)
{
Animation test = AnimationUtils.loadAnimation(this, R.anim.move_down);
character.startAnimation(test);
character.setVisibility(View.GONE);//when returns to original position, make it invisible
character.setY(character.getY() + character.getHeight());//move to new location
character.setVisibility(View.VISIBLE);//make it visible
}
After animation ends, it returns to the original location, so you need to make it invisible and then move it to the new location where it moved to in the animation and then make it visible. When running, it should appear seamless.
I have a problem with tween animation in android , I try to move an ImageView item from center of screen to top of screen but after end of transform ImageView returns to first position! I use this code:
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/bounce_interpolator"
android:fromYDelta="0%"
android:toYDelta="-1500%"
android:duration="3000"
android:startOffset="3000">
</translate>
private void RunAnimations() {
Animation animation = AnimationUtils.loadAnimation(this, R.anim.move_up_maxname);
animation.reset();
ImageView maxName = (ImageView) findViewById(R.id.imageView1);
maxName.clearAnimation();
maxName.startAnimation(animation);
}
Can anyone help me?
Thanks
You need to take a look at setFillAfter:
If fillAfter is true, the transformation that this animation performed will persist when it is finished.
Use AnimationListener and in onAnimationEnd() change the position of ImageView(Last point).
animation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation anim)
{};
public void onAnimationRepeat(Animation anim)
{};
public void onAnimationEnd(Animation anim)
{
//Change imageview position using LayoutParameters
};
});
add line
animation.setFillAfter(true);
I'm trying to set up 2 layouts - I want one layout to slide up, and when it's finished another layout should fade in.
I've managed to get it working, but at the end of the two animation and first layout blinks once.
How can I solve it?
Here's the code(first layout is named titleLay and the second one is called registerLayout)-
final TranslateAnimation slide = new TranslateAnimation(0, 0, 0,-100 );
slide.setDuration(500);
slide.setFillAfter(true);
slide.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
RelativeLayout registerLayout = (RelativeLayout) findViewById(R.id.registerLay);
Animation fadeInAnimation = AnimationUtils.loadAnimation(con, R.anim.fade_in_anim);
registerLayout.startAnimation(fadeInAnimation);
registerLayout.setVisibility(View.VISIBLE);
}
});
titleLay.startAnimation(slide);
And that's the XML code of the R.anim.fade_in_anim-
<?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="500"/>
</set>
Edit: If I use other types of animations(fade out, slide etc...) it works fine, without flicking.
Thanks!
If you are using animateLayoutChanges in your layout file in combination with the animation onAnimationEnd toggling the View visibility it will result in two animations running and the view flashing or blinking. Setting view visibility causes the layouts animateLayoutChanges to run and to fade the view in once and then the animation you created causes a second animation to run as well.
Instead of setting the view's visibility, try to use the setAlpha function.
registerLayout.setAlpha(0f); //invisible
registerLayout.setAlpha(1f); //visible
Remove the declerations and initilizations from your onAnimationEnd, the initilization may take a long time since the XML needs to be parsed from resources,
put thouse two lines in your onCreate:
RelativeLayout registerLayout = (RelativeLayout) findViewById(R.id.registerLay);
Animation fadeInAnimation = AnimationUtils.loadAnimation(con, R.anim.fade_in_anim);
and set visibility to slide:
final TranslateAnimation slide = new TranslateAnimation(0, 0, 0,-100 );
slide.setDuration(500);
slide.setFillAfter(true);
slide.setAnimationListener(new
AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
registerLayout.startAnimation(fadeInAnimation);
registerLayout.setVisibility(View.VISIBLE);
}
});
titleLay.startAnimation(slide);
titleLay.setVisibilty(View.VISIBLE);
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