I want to make 2 animation on activity for 2 images, and I want to do it with 2 conditions:
1. I want to start the animation after the activity finished to load to page, so instead of putting animation code under onCreate i put it under onResume is that OK? There is a better way to do it?
2. I want the second animation will start only after the first animation is finished...
Thanks
You'll want to use an Animation.AnimationListner You can set one on your first animation that will get a callback when the animation is complete. Inside that callback you can add the code that will start the second animation.
Depending on the API level you are coding for you can use AnimationSet or AnimatorSet. Also if you are extending View or one of its subclasses you can override View.onAnimationStart() and View.onAnimationFinish(). Or use the listener Tim mentions.
public class SplashActivity extends Activity{
Animation FadeInanimation, FadeOutanimation;
ImageView img;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
img= (ImageView) findViewById(R.id.img);
//Your Code Block....
FadeInanimation = AnimationUtils.loadAnimation(this,R.anim.image_fadein);
//FadeInanimation.setRepeatCount(Animation.INFINITE);
//FadeInanimation.setRepeatMode(Animation.RESTART);
FadeInanimation.setAnimationListener(FadeInAnimationListener);
FadeOutanimation = AnimationUtils.loadAnimation(this,R.anim.image_fadeout);
//FadeOutanimation.setRepeatCount(Animation.INFINITE);
//FadeOutanimation.setRepeatMode(Animation.RESTART);
FadeOutanimation.setAnimationListener(fadeOutAnimationListener);
img.startAnimation(FadeInanimation);
}
AnimationListener FadeInAnimationListener = new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
plane.startAnimation(FadeOutanimation);
}
};
}
Related
I have a ViewPager in my app, and I'd like it to shake when it is loaded for the first time. This is to show the user that there are more pages available. How can I achieve that programmatically?
However, I don't want the pager to automatically scroll to the next page.
ViewPager has a method for swiping programmatically: fakeDragBy
https://developer.android.com/reference/android/support/v4/view/ViewPager.html#fakeDragBy(float)
Here's how you can achieve this:
Call viewPager.beginFakeDrag()
Start an animator. In the AnimatorUpdateListener override onAnimationUpdate so it calls viewPager.fakeDragBy()
In the AnimatorListener override onAnimationEnd so it calls viewPager.endFakeDrag() After this call, the ViewPager should settle back to the initial page.
vpaliyX's answer using translation won't show the next page. You need to use fakeDragBy so that the user can briefly see the edge of the next page.
As requested, here is a code snippet:
private float drag;
...
#Override
protected void onResume() {
super.onResume();
mViewPager.postDelayed(new Runnable() {
#Override
public void run() {
mViewPager.beginFakeDrag();
drag = 0;
float density = getResources().getDisplayMetrics().density;
// 120 is the number of dps you want the page to move in total
ValueAnimator animator = ValueAnimator.ofFloat(0, 120 * density);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float progress = (float) valueAnimator.getAnimatedValue();
mViewPager.fakeDragBy(drag - progress);
drag = progress;
}
});
animator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) { }
#Override
public void onAnimationEnd(Animator animator) {
mViewPager.endFakeDrag();
}
#Override
public void onAnimationCancel(Animator animator) { }
#Override
public void onAnimationRepeat(Animator animator) { }
});
animator.setDuration(400);
animator.start();
}
}, 300);
}
I put in a 300 ms start delay. I don't really know if that's necessary or not.
Note the expression drag - progress which gives a negative number. To get a leftward swipe, you have to use a negative value.
Also note that I didn't include any code to determine if this was the first time the app was opened.
You can play with the start delay, the animation duration, and the number of dps to swipe until you get the effect you are looking for.
If you want to shake it, you can use animation for it.
I had done the same stuff for FloatingActionButton, and it worked perfectly.
For ViewPager check out this code:
ObjectAnimator shakeAnimation=ObjectAnimator.ofFloat(yourViewPager,View.TRANSLATION_X,-25f,25f);
shakeAnimation.setDuration(100);
shakeAnimation.setRepeatCount(2);
shakeAnimation.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
yourViewPager.setTranslationY(0f);
}
});
shakeAnimation.start();
You can adjust the translation as convenient for, in my case it's just [-25,25].Also you can set a duration of animation, and the repeat count.
You can use this code for your ViewPager when the data has been loaded for the first time, however, you need to determine when the data has been loaded for the first time. But I don't think you will have problems with that.
Good luck!
I want the Layout"authentification" to appear after the Splash screen, in my application it's appear by default please some one help me!!!!!
pleaaase i need help
public class Splash extends Activity {
LinearLayout ln;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splashh);
ln = (LinearLayout) findViewById(R.id.LinLaySpalScrenLogin);
final ImageView iv = (ImageView) findViewById(R.id.imageView);
final Animation an = AnimationUtils.loadAnimation(getBaseContext(),R.anim.rotate);
final Animation an2 = AnimationUtils.loadAnimation(getBaseContext(),R.anim.abc_fade_out);
iv.startAnimation(an);
an.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
iv.startAnimation(an2);
finish();
ln.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
}
You can set android:visibility="gone" in your LinearLayout xml file that contains your Splash Screen and then call yourlayout.setVisibility(View.VISIBLE); after you finish your animation.
Also your activity will end as soon as your animation finishes since you have called finish() before ln.setVisibility(View.VISIBLE); Try to remove finish() and only call it on some event such as Button click or something like that
You have ln.setVisibility(View.VISIBLE); after finish();. Try changing to :-
ln.setVisibility(View.VISIBLE);
finish();
However, this will probably not work as because as soon as the make the layout visible. The activity would finish. You probably want to display the authentication in another activity after the splash has completed.
these are just the methods i can override during animationListener.
http://developer.android.com/reference/android/view/animation/Animation.AnimationListener.html
Animation animation
animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.device_box);
animation.setAnimationListener(new AnimationListener(){
#Overridepublic void onAnimationEnd(Animation arg0) {}
#Override public void onAnimationRepeat(Animation animation) {}
#Override public void onAnimationStart(Animation animation) {}});
I think adding a thread in onAnimationStart and stop it on onAnimationEnd and getting the coordinates with a loop inside the thread, this may work.
But i think that i could get some problems with buttons because, when animating them in this way, only the background moves, not button area itself
In this case, i have to investigate more with buttons
What do you think about this, is there another way to achieve what i want?
Is this the better way to do it ?
I researched, and what I got is this, not X and Y but can handle the data as get what has been animated as time.
ObjectAnimator anim = ObjectAnimator.ofFloat(box_image, "translationX", 0 , cant);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator arg0) {
double f = Math.round(arg0.getAnimatedFraction()*1000.0)/1000.0;
Log.d("datos", ""+f);
}
});
anim.setDuration(1000);
anim.start();
I want to animate a scale an ImageView vertically, wait, then perform another scale on the same ImageView. I've simplified the code below but it's essentially what I want to do:
ScaleAnimation animate = new ScaleAnimation(1,1,1,2);
animate.setDuration(1000);
animate.fillAfter(true);
ScaleAnimation animateAgain = new ScaleAnimation(1,1,2,1);
animate.setDuration(1000);
animate.fillAfter(true);
view.startAnimation(animate);
view.startAnimation(animateAgain);
I've tried multiple ways of waiting for the first animation to finish (Thread.sleep etc.) but it doesn't seem to make any difference. I assume the animation is rendered in the onDraw method or something? I'm not entirely sure how scale animations work so I can't really grasp how to solve my problem.
What's the simplest way of doing what I want to accomplish?
Thanks guys :)
There are a couple of ways:
Attach an AnimationListener to your animations.
ScaleAnimation animate = new ScaleAnimation(1,1,1,2);
animate.setDuration(1000);
animate.fillAfter(true);
animate.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
ScaleAnimation animateAgain = new ScaleAnimation(1,1,2,1);
animateAgain.setDuration(1000);
animateAgain.fillAfter(true);
view.startAnimation(animateAgain);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}});
view.startAnimation(animate);
Alternately, you can set an animation delay for your second animation.
ScaleAnimation animateAgain = new ScaleAnimation(1,1,2,1);
animateAgain.setDuration(1000);
animateAgain.fillAfter(true);
animateAgain.setStartOffset(firstAnimationDuration + delay);
I have code like this:
else if (v == mSettings)
{
if (disappearView.getVisibility() == View.VISIBLE)
{
AlphaAnimation fadeOutAnimation = new AlphaAnimation(1, 0); // start alpha, end alpha
fadeOutAnimation.setDuration(1000); // time for animation in milliseconds
fadeOutAnimation.setFillAfter(true); // make the transformation persist
Animation out = AnimationUtils.makeOutAnimation(this, true);
disappearView.startAnimation(out);
disappearView.setVisibility(View.INVISIBLE);
out.setAnimationListener(new Animation.AnimationListener()
{
public void onAnimationEnd(Animation animation)
{
disappearView.setVisibility(View.GONE);
Animation in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
bannerView.startAnimation(in);
bannerView.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationRepeat(Animation animation) { }
#Override
public void onAnimationStart(Animation animation) { }
});
}
else {
Animation in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
disappearView.startAnimation(in);
disappearView.setVisibility(View.VISIBLE);
bannerView.setVisibility(View.INVISIBLE);
bannerView.setVisibility(View.GONE);
}
}
It all works apart from this section in the animationListener:
Animation in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
It wants a valid context but it is receiving an animationListener, what context do I give it, context really confuses me here.
Change it to:
Animation in = AnimationUtils.loadAnimation(MyActivityName.this, android.R.anim.fade_in);
It wants an instance of any class that extends Context. Since it is inside an anonymous inner class, when you use this you are referring to the inner class instance, and not to your Activity. My snippet refers to the Activity class that wraps the anonymous inner class. Since Activity extends Context, this is a valid argument.
Inside the listener, this is referring to the Listener. Try using ActivityName.this