I need an animation for an image in my application. where two balls size images should coming from the right and left corner and move all over the screen infinity on click of button
please help.
It sounds like you are looking for a TranslateAnimation
TranslateAnimation allows you to create a simple animation from one (x,y) position to another (x,y) position.
If you wanted it to run infinitely, you might do something like this:
TranslateAnimation translateAnimation = new TranslateAnimation(0,0,100,100);
translateAnimation.setRepeatMode(Animation.INFINITE);
translateAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
/* Set new from values, then generate new to values here, then restart animation */
}
});
View myView = new View();
myView.startAnimation( translateAnimation);
In my onAnimationRepeat method, I would reset the fromX and fromY values of the animation, and generate new toX and toY values, then start it over again.
This will only move the view from one point to another, if you need it to do multiple different animations at once, you might need to create a custom animation.
Related
I am developing two different animations as shown below.
The first animation I was able to develop using Object animator and FrameLayout. Basically, I created the two rectangles and the candlesticks inside a gravity-centered frame layout. When made to start the animation, I used the object animator to move them on either side and return to the initial position.
My second animation is the issue point here. In this animation, the rectangles will go on a circular path from their initial point and return back to their initial point. During this course, the candles need to move in sync with the rectangle giving a spring effect (or) kind of a sliced rectangle.
My initial idea was to re-use the first animation and just as the first animation runs, I would run a rotate animation on the frameLayout view.
But that doesn't seem to work wherein rotation works but the translation doesn't.
Can someone say if I have taken the right approach or should I use some other way to achieve this?
Adding the code that I have tried, but didn't work.
Animation anim = new RotateAnimation(0.0f, 360.0f, pivotX, pivotY);
anim.setDuration(500);
anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
for(View view : mCandleSticks) {
ObjectAnimator anim1 = ObjectAnimator.ofFloat(view, "translationX", view.getX(), targetPos, view.getX());
anim1.setDuration(500);//set duration
anim1.start();//start animation
}
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
});
frameLayout.startAnimation(anim);
Thanks in advance.
I am doing an animation inside a fragment.
I have 2 views on top of each other, one of them set on View.GONE.
when I press a button I want my 2nd fragment to translate animation from the bottom to top.
I am doing it fine and it's working great,
the problem is that in my first run, the xml view is gone, but he is in the same Y he is suppose to be.
so the first animation I do isn't doing anything, just switch from GONE to VISIBLE, after that, I press dismiss and the fragment goes away and comes back just like I want too.
my problem is just the first run.
how can I set my view Y to be 100% below my screen?
here's the code I use :
private void moreCustomAnimation() {
int yOffset = moreMenuFrameLayout.getMeasuredHeight();
TranslateAnimation moveAnim = new TranslateAnimation(0, 0, yOffset, 0);
moveAnim.setDuration(500);
moveAnim.setFillAfter(true);
blackView.setVisibility(View.VISIBLE);
moreMenuFrameLayout.setVisibility(View.VISIBLE);
moreMenuFrameLayout.startAnimation(moveAnim);
moveAnim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
}
on the way out of the screen I use the same code just switch the
yOffset to the other Y integer, and set the view to GONE at animation end.
thanks a lot in advance for any help !
You can use the onGlobalLayout event to set the position of the view.
Like this:
moreMenuFrameLayout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
moreMenuFrameLayout.setTranslationY(moreMenuFrameLayout.getMeasuredHeight());
moreMenuFrameLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
This event happens when your views get their actual size and position before being drawn to the screen. However, they happen every time the view is drawn so you must remember to remove the listener right after the first time.
HTH
First time you can add the 'yOffset' value to the view orginal points
moreMenuFrameLayout.setY(currentYpostition + yOffset)
and this will place the view to the bottom of the screen. You can enable the visibility when the animation starts.
I need my listview to hide and show using alternative touches. Hence for hiding the listview on the left side of the screen am using animation
Animation animation = new TranslateAnimation(-100, 0,0, 0);
animation.setDuration(100);
animation.setFillAfter(true);
lv.startAnimation(animation);
lv.setVisibility(0);
and for displaying am using
lv.setVisibility(View.VISIBLE);
My problem is list view is not getting hide. It will go leftside and coming back again. I don't know how to hide listview to the left edge completely on touch. Please help in achieving this
// To animate view slide out from left to right
public void slideToRight(View view){
TranslateAnimation animate = new TranslateAnimation(0,view.getWidth(),0,0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
view.setVisibility(View.GONE);
}
// To animate view slide out from right to left
public void slideToLeft(View view){
TranslateAnimation animate = new TranslateAnimation(0,-view.getWidth(),0,0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
view.setVisibility(View.GONE);
}
// To animate view slide out from top to bottom
public void slideToBottom(View view){
TranslateAnimation animate = new TranslateAnimation(0,0,0,view.getHeight());
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
view.setVisibility(View.GONE);
}
// To animate view slide out from bottom to top
public void slideToTop(View view){
TranslateAnimation animate = new TranslateAnimation(0,0,0,-view.getHeight());
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
view.setVisibility(View.GONE);
}
Finally i find the answer and it is very simple modification in co-ordinate values. And the code is
Animation animation = new TranslateAnimation(0,-200,0, 0);
animation.setDuration(2000);
animation.setFillAfter(true);
listView1.startAnimation(animation);
listView1.setVisibility(0);
Here am setting negative value at second co-ordinate cause from o it is moving twowards negative side which means the view is moving twowards inner left side.
If you want to hide your View, use
View.INVISIBLE // constant value 4
or
View.GONE // constant value 8
You are currently using the value 0 which is the constant value of View.VISIBLE.
I suppose you want to hide the ListView after animating it?
But you are showing the ListView directly after starting the animation. Take a look at AnimationListener and hide the ListView
onAnimationEnd(...)
For example:
// assuming the listview is currently visible
Animation animation = new TranslateAnimation(-100, 0,0, 0);
animation.setDuration(100);
animation.setFillAfter(true);
animation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
lv.setVisibility(View.GONE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
lv.startAnimation(animation);
for the general understanding of what you don't know, i found you another post that explains it very good!! The View and its animation work a bit different as it might be expected!
https://stackoverflow.com/a/5888969/2074990
I have two buttons.When first button is pressed i am translating my layout layout to top and from the top of the screen another layout will come.But my issue is when came back to first layout the click events of the second layout still get fired at its previous position.So what is the Solution of it?I found a lot here on SO as well as on Google but still cannot get the right solution yet.So Please someone help me for my this issue.Thanks in Advance.
TranslateAnimation tr1 = new TranslateAnimation(0, 0, 0, -1100);
tr1.setDuration(1000);
tr1.setFillAfter(true);
layout_login.startAnimation(tr1);
tr1.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
layout_signup.setVisibility(View.VISIBLE);
TranslateAnimation tr2 = new TranslateAnimation(0, 0,
-1100, 0);
tr2.setDuration(1000);
tr2.setFillAfter(true);
tr2.setInterpolator(MainActivity.this,
android.R.anim.linear_interpolator);
layout_signup.startAnimation(tr2);
tr2.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
home_activity_btn_login.setEnabled(true);
}
});
}
});
I think this is a bug with the old animator schemes (I beleive a pretty well known bug, involving fill after not working sometimes). Try using ObjectAnimator instead
Here is an example,
ObjectAnimator oa = ObjectAnimator.ofFloat(view, "translationX", 0, 100f);
oa.setDuration(1000);
oa.start();
If you want to move in the Y direction, you can use translationY. If you want to move in both directions, you need a translationX and translationY, and use an AnimatorSet to play simultaneously.
Check out this comment to this question. Using the old Animation API, apparently dispite fillAfter(true), the buttons click position remains the same. This confirms your issue. So just use the new API, and you should be in good shape.
I'm trying to slide in a view on a RelativeLayout via an animation. Once the view is in place I have to alter the layout params of layout so that the new view doesn't block existing content. I call the code to update the layout after the animation but it occurs before the animation causing a block of area to be blank during the animation.
The following screens are before animation, during and after:
Here is the code. The relative layout is adjusted in onShowAd.
float fromY = getAdHeight();
float toY = 0;
TranslateAnimation slide = new TranslateAnimation(0,0,fromY,toY);
slide.setDuration(ANIMATION_RATE);
slide.setFillAfter(true);
mAdLayout.startAnimation(slide);
onShowAd();
mAdLayout.setVisibility(View.VISIBLE);
I tried differing orders of calling visible and other things as well as using a handler to postDelayed onShowAd() to wait the same amount of time as the ANIMATION_RATE however what happened you'd stare at the black box for the time it was post delayed and then have to wait for the animation so it was worse. In windows there's an API call LOCKWINDOWUPDATE that I could pass in a window handle to prevent updating...is there anything equivalent for a view in Android? Or any other ideas?
Incidentally when sliding the view OUT it works fine. Here is the code going the other way. onHideAd is where the layoutparams are modified in this one.
float toY = ((View) mAdLayout.getParent()).getBottom();
float fromY = 0;//toY - mAdLayout.getHeight();
TranslateAnimation slide = new TranslateAnimation(0,0,fromY,toY);
slide.setDuration(ANIMATION_RATE);
slide.setFillAfter(true);
mAdLayout.startAnimation(slide);
mAdLayout.setVisibility(View.GONE);
onHideAd();
Thanks for any suggestions!
EDIT: I added the listener and that doesn't take care of it. I have isolated it to the following code which in in the "onShowAd()" routine:
RelativeLayout.LayoutParams params = (android.widget.RelativeLayout.LayoutParams) mainFragmentContainer.getLayoutParams();
params.addRule(RelativeLayout.ABOVE, mAdLayout.getId());
mainFragmentContainer.setLayoutParams(params);
I've tried to further separate it by calling it with a handler.postDelayed and it seems like anywhere I place it in the chain of events causes it to occur BEFORE the animation itself shows. Very odd! :-(
This is the updated showAd routine. I tried reordering some of the calls as well.
float fromY = getAdHeight();
float toY = 0;
TranslateAnimation slide = new TranslateAnimation(0,0,fromY,toY);
slide.setDuration(ANIMATION_RATE);
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) {
onShowAd();
}
});
mAdLayout.setVisibility(View.VISIBLE);
mAdLayout.startAnimation(slide);
You should use an AnimationListener to accomplish what you are looking for. The problem you are running into is caused because the call to start animation returns instantly even though the animation doesn't complete for the time set to ANIMATION_RATE.
Ex for slide in:
float fromY = getAdHeight();
float toY = 0;
TranslateAnimation slide = new TranslateAnimation(0,0,fromY,toY);
slide.setDuration(ANIMATION_RATE);
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) {
onShowAd();
}
});
mAdLayout.setVisibility(View.VISIBLE);
mAdLayout.startAnimation(slide);