I have used an imageView to display 5 nearly equal images randomly on the screen.The thing is every image is turned off and immediately next one is displayed.So that the viewer can easily find that image is being changed.Is it possible to add animation effects to imageView? (like, one image slowly fades out,in the meanwhile another image fades in)
u can modify ur self
ImageView img_view= (ImageView) findViewById(R.id.DemoImage);
int images[] = { R.drawable.image1, R.drawable.image2,R.drawable.image3 };
animate(img_view, images, 0,false);
private void animate(final ImageView imageView, final int images[], final int imageIndex, final boolean forever) {
int fadeInDuration = 1000;
int timeBetween = 5000;
int fadeOutDuration = 1000;
imageView.setVisibility(View.INVISIBLE);
imageView.setImageResource(images[imageIndex]);
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(fadeInDuration);
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setStartOffset(fadeInDuration + timeBetween);
fadeOut.setDuration(fadeOutDuration);
AnimationSet animation = new AnimationSet(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);
}
else {
if (forever){
animate(imageView, images, 0,forever);
}
}
}
});
}
Related
I'm trying to make an animation of an imageview that revolves around a circle shape.
Here is the currrent code who works but without repeating the animation with different values:
public void runAnimation(){
ImageView worldView=findViewById(R.id.imageView);
int radius=worldView.getHeight()*30/70;
int centerx = worldView.getLeft()+radius;
int centery = worldView.getTop()+radius;
//List<Animator> myList = new ArrayList<>();
for (int i=0;i<360;i++) {
/*---I calculate the points of the circle---*/
int angle= (int) ((i * 2 * Math.PI) / 360);
int x= (int) (centerx+(radius*Math.cos(angle)));
int y= (int) (centery+(radius*Math.sin(angle)));
/*---Here carView is the ImageView that need to turn around the worldView---*/
ObjectAnimator animatorX =ObjectAnimator.ofFloat(carView, "x",x);
ObjectAnimator animatorY =ObjectAnimator.ofFloat(carView, "y",y);
ObjectAnimator animatorR =ObjectAnimator.ofFloat(carView, "rotation", i);
animatorX.setDuration(500);
animatorY.setDuration(500);
animatorR.setDuration(500);
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.playTogether(animatorX,animatorY,animatorR);
animatorSet.start();
//myList.add(animatorSet);
}
//AnimatorSet animatorSet=new AnimatorSet();
//animatorSet.playSequentially(myList);
}
The commentary ("//") are here to illustrate what I want to create.
Thank in advance for your help.
You can add a listener to each AnimatorSet by using addListener(Animator.AnimatorListener listener).
for (int i=0;i<360;i++) {
// ...skipped some lines here...
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.playTogether(animatorX,animatorY,animatorR);
myList.add(animatorSet);
animatorSet.addListener(myListener);
}
where myListener is defined as follows:
private Animator.AnimatorListener myListener = new Animator.AnimatorListener(){
#Override
public void onAnimationStart(Animator animation){
// no op
}
#Override
public void onAnimationRepeat(Animator animation){
// no op
}
#Override
public void onAnimationCancel(Animator animation){
// no op
}
#Override
public void onAnimationEnd(Animator animation){
startNextAnimation();
}
};
In addition to that, you need some variable private int counter; to iterate over the list.
Before starting the first animation, you set it to zero:
counter = 0;
myList.get(0).start();
To start the next animation (if there is one left):
private void startNextAnimation(){
counter++;
if(counter == myList.size()){
return;
}
myList.get(counter).start();
}
I have two animations that are to occur one after the other. The first one works as expected, however, the 2nd animation jumps to the very top of the screen at the first animation's onAnimationEnd() call. A balloon ImageView "floats" up to the center of the screen, and it is supposed to expand (the rest will be implemented later. I'm just trying to get this part to work). The first animation is pure Java, not xml.
The second animation's xml (bounce.xml):
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="2000"
android:fromXScale="1.0"
android:toXScale="2.0"
android:fromYScale="1.0"
android:toYScale="2.0"
android:pivotX="50%"
android:pivotY="50%"/>
</set>
My BounceInterpolator class:
public class BounceInterpolator implements Interpolator {
private double mAmplitude = 1;
private double mFrequency = 10;
BounceInterpolator(double amplitude, double frequency) {
mAmplitude = amplitude;
mFrequency = frequency;
}
public float getInterpolation(float time) {
return (float) (-1 * Math.pow(Math.E, -time/ mAmplitude) * Math.cos(mFrequency * time) + 1);
}
}
And finally the class where it all happens:
public class CelebrateActivity extends AppCompatActivity {
ImageView purple_balloon_1;
Animation anim;
Animation bounceAnim;
RelativeLayout layout;
MediaPlayer mediaPlayer;
DisplayMetrics displayMetrics;
static int height;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_celebrate);
displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
height = displayMetrics.heightPixels;
mediaPlayer = MediaPlayer.create(this, R.raw.first_love);
mediaPlayer.start();
layout = findViewById(R.id.relativeLayout);
purple_balloon_1 = findViewById(R.id.purple_balloon_1);
slideUp();
}
public void slideUp() {
Animation slide = null;
slide = new TranslateAnimation(0, 0, height, height / 2 - 100);
slide.setDuration(15000);
slide.setFillAfter(true);
slide.setFillEnabled(true);
purple_balloon_1.startAnimation(slide);
bounceAnim = AnimationUtils.loadAnimation(CelebrateActivity.this, R.anim.bounce);
BounceInterpolator interpolator = new BounceInterpolator(0.2, 20);
bounceAnim.setInterpolator(interpolator);
slide.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
purple_balloon_1.startAnimation(bounceAnim); //Where the 2nd animation is supposed to start. It works, but it jumps to the top of the screen.
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
}
Why does it jump to the top of the screen, and how can I set the Y coordinate to the location of the ImageView to prevent said jumping?
#pskink - Thank you for the tips. I went with ObjectAnimator and AnimatorSet. I got rid of both of my xml files and the BounceInterpolator class, which saved a lot of code in the process. The animation is working perfectly now.
Again, thank you.
public class CelebrateActivity extends AppCompatActivity {
ImageView purple_balloon_1;
//Animation slide;
//Animation grow;
AnimatorSet animatorSet;
RelativeLayout layout;
MediaPlayer mediaPlayer;
DisplayMetrics displayMetrics;
static int height;
public static final String TAG = "CelebrateActivity.this";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_celebrate);
displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
height = displayMetrics.heightPixels;
mediaPlayer = MediaPlayer.create(this, R.raw.first_love);
mediaPlayer.start();
layout = findViewById(R.id.relativeLayout);
purple_balloon_1 = findViewById(R.id.purple_balloon_1);
animatorSet = new AnimatorSet();
ObjectAnimator slide = ObjectAnimator.ofFloat(purple_balloon_1, "translationY", height, height / 2);
slide.setDuration(15000);
ObjectAnimator growX = ObjectAnimator.ofFloat(purple_balloon_1, "scaleX", 1.5f);
growX.setDuration(500);
ObjectAnimator growY = ObjectAnimator.ofFloat(purple_balloon_1, "scaleY", 1.5f);
growY.setDuration(500);
animatorSet.playTogether(growX, growY);
animatorSet.playSequentially(slide, growX);
animatorSet.start();
}
}
I am trying to replicate an animation used in Quartz news app for android.
Here is my code that I am using to accomplish this.
//On clicking button start animation
private void handleActionButtonClick(Button actionButton) {
Log.d(TAG, "Action button clicked");
handler.postDelayed(new Runnable() {
#Override
public void run() {
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(messageAdapter.getItemCount() - 1);
if (viewHolder instanceof OutgoingMessageViewHolder) {
final OutgoingMessageViewHolder outgoingTextMessageViewHolder = (OutgoingMessageViewHolder) viewHolder;
View messageView = outgoingTextMessageViewHolder.getTextView();
int[] actionButtonPos = new int[2];
actionButton.getLocationInWindow(actionButtonPos);
int startX = actionButtonPos[0];
int startY = actionButtonPos[1];
int[] newMessagePos = new int[2];
messageView.getLocationInWindow(newMessagePos);
int x = newMessagePos[0] - startX;
int y = newMessagePos[1] - startY;
AnimatorSet flySet = new AnimatorSet();
Animator flyX = ObjectAnimator.ofFloat(actionButton, View.TRANSLATION_X, (float) x);
Animator flyY = ObjectAnimator.ofFloat(actionButton, View.TRANSLATION_Y, (float) y);
flySet.playTogether(flyX, flyY);
flySet.setDuration(450);
flySet.setInterpolator(new OvershootInterpolator(1.0f));
flySet.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
outgoingTextMessageViewHolder.getTextView().setText(actionButton.getText());
outgoingTextMessageViewHolder.itemView.setAlpha(1.0f);
}
});
AnimatorSet flyAndFadeSet = new AnimatorSet();
ObjectAnimator fade = ObjectAnimator.ofFloat(actionButton, View.ALPHA, new float[]{0.0f}).setDuration(200);
flyAndFadeSet.playSequentially(flySet, fade);
final Button button = actionButton;
flyAndFadeSet.addListener(new BaseAnimationListener() {
public void onAnimationEnd(Animator animation) {
button.setAlpha(0.0f);
hideUserActions();
}
});
flyAndFadeSet.start();
hideOtherActions(actionButton, false);
}
}
}, messageAnimator.getAddDuration());
}
But I am not able to get desired results as the position on end animation and view of message doesn't match with each other. Also I want to know is this the right way to do this.
Link to Quartz app implementation
Quartz app chat animation
Link to my implementation image
My chat app animation
In my app a large text in textview scroll up automatically with translate animation, and i designed two button for decrease and increasing speed, but when I change the duration it's work after last duration so it is not on-the-fly, but I want whenever I clicked, in that moment duration changed.In fact I want to do like how to change the duration of AnimationDrawable on the fly/runtime? ,but, with "Translation animation"
Here is what I did for randomly blinking light
final ImageView imageLight = (ImageView)findViewById(R.id.imageLight);
lastLightAlpha = (float) Math.random();
AlphaAnimation blinkLightAnimation = new AlphaAnimation(1.0f, lastLightAlpha);
blinkLightAnimation.setDuration((long) (Math.random() * 3000));
blinkLightAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
float newAlpha = (float) Math.random();
AlphaAnimation blinkLightAnimation = new AlphaAnimation(lastLightAlpha, newAlpha);
blinkLightAnimation.setAnimationListener(this);
blinkLightAnimation.setDuration((long) (Math.random() * 3000));
lastLightAlpha = newAlpha;
imageLight.startAnimation(blinkLightAnimation);
}
});
imageLight.startAnimation(blinkLightAnimation);
You can also reset your animation by
gearAnimation.cancel();
gearAnimation.reset();
I hope you can use parts of this code to solve your issue.
In my application i am able to animate the image from source location to destination location and repeating the animation 5 times using animation.setRepeatCount(5);
But i want to change the destination location(yDelta) after each repetition.
For example :
destination Ydelta is 2, after first repetition need to change the ydelta to 3 and next repetition ydelta to 4 so on... up to 5 repetitions....
Below is my animation code:
int sourceCoords[] = new int[2];
int targetCoords[] = new int[2];
int xDelta;
int yDelta;
sourceImage.getLocationOnScreen(sourceCoords);
targetImage.getLocationOnScreen(targetCoords);
xDelta = targetCoords[0] - sourceCoords[0];
yDelta = targetCoords[1] - sourceCoords[1];
sourceImage.bringToFront();
TranslateAnimation animation = new TranslateAnimation(0, xDelta, 0, yDelta);
animation.setDuration(400);
animation.setFillAfter(false);
animation.setRepeatCount(5);
sourceImage.startAnimation(animation);
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(final Animation animation) {
sourceImage.bringToFront();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
});