I have a layout which moves on a specific user action. The layout moves a bit up, but buttons are clickable where they were before animation. How do I update the layout's children onAnimationEnd?
Here I could not find the answer, but I understood the problems is in how the Android Layout system is build.
I tried:
popupLayout.requestLayout();
And:
popupLayout.invalidate();
Neither worked. Any other Ideas on how to update the contained buttons?
Update
Here is how I do the animation:
Animation slide = null;
slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
0.0f, Animation.RELATIVE_TO_SELF, -0.3f);
slide.setDuration(300);
slide.setFillAfter(true);
slide.setFillEnabled(true);
popupLayout.startAnimation(slide);
// and then the AnimationListener
Update
I tried to set LayoutParams and it does not work neither.
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
dialogLayout.getWidth(), dialogLayout.getHeight());
// lp.setMargins(0, 0, 0, 0);
dialogLayout.setLayoutParams(lp);
Inside onAnimationEnd() you have to update your layout parameters of the view which you are animating, in your case it's LinearLayout. You have to update view in respect of the parent. If your animated view parent is e.g. RelativeLayout you can call this:
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) animatedView.getLayoutParams();
//TODO modify params
animatedView.setLayoutParams(params);
animatedView.requestLayout();
I think this should work. You can also try calling requestLayout() on the parent.
There is also tutorial on YT about View animations. Chet Haase talks about handling animations including TranslateAnimation. I don't have time to watch but maybe you will find there your answer.
Update
If you manage successfully set layout params after animation, don't forget to remove line:
slide.setFillAfter(true);
Remember that animation modify ONLY drawing coordinates relative to the view position. In other words, it creates an offset to original position which has to be reset after animation ends. Method setFillAfter(true) skip reseting this offset.
setContentView(rootLayout) will do the job... not working
Related
I am animating in the following way,
There are 2 layouts (both are relative layouts), layout1, which will be hidden initially, layout2 will be shown to the user initially.
once the animation starts layout1, will be made visible and layout2 will be scaled using the animator as follows,
Animator scalexAnimator = ObjectAnimator.ofFloat(layout2, "scaleX", 1f, 0f);
Animator scaleyAnimator = ObjectAnimator.ofFloat(layout2, "scaleY", 1f, 0f);
Animator pivotxAnimator = ObjectAnimator.ofFloat(layout2, "pivotX", <maxWidth>);
Animator pivotyAnimator = ObjectAnimator.ofFloat(layout2, "pivotY", <maxheight/2>);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(pivotxAnimator, pivotyAnimator, scalexAnimator, scaleyAnimator);
animatorSet.start();
This starts the animation and the layout2 gets shrinked,but the aspect ratio is never maintained, what I mean to say is the animation follows these steps,
Firstly the height reduces.
Next the width gets reduced.
Height reduces again.
Width again.
this goes on and it will stop once the final given ratio(0.5) is achieved.
This does not give shrinking effect, I tried with animation class as follows,
Animation shrinkAnimation = new ScaleAnimation(1,0.5f,1,05f,Animation.RELATIVE_TO_SELF,1f, Animation.RELATIVE_TO_SELF, 0.5f);
layout2.startAnimation(shrinkAnimation);
this will work perfectly and I will get a exact shrinking effect, aspect ratio is maintained, but the problem I face in the above implementation is the position of the layout2 is changed, but the button retain their position (layout2 has 4 buttons and button click works on the old button positions, even though the user can't see any buttons there, I read in some posts that this is expected), so I had to disable the buttons manually, this is a overhead so I wanted to avoid using Animation class, and went for ObjectAnimator.
So is there a way in ObjectAnimator to get the same shrinking effect?
I am animating an ImageView from the center of the screen to the top-left using an Animation Set.I am Translating and Scaling the View.
Heres the code snippet.
AnimationSet tempAnimation=new AnimationSet(true);
TranslateAnimation anim = new TranslateAnimation( 0,xPos, 0, yPos );
anim.setFillAfter( true );
anim.setFillEnabled(true);
ScaleAnimation scaleanimation = new ScaleAnimation(1, (float)0.22, 1, (float)0.22, Animation.RELATIVE_TO_SELF, (float)0.5, Animation.RELATIVE_TO_SELF, (float)0.5);
scaleanimation.setDuration(1000);
scaleanimation.setFillEnabled(true);
scaleanimation.setFillAfter(true);
tempAnimation.addAnimation(scaleanimation);
tempAnimation.addAnimation(anim);
tempAnimation.setDuration(1000);
// This takes care that the ImageViews stay in their final positions after animating .
tempAnimation.setFillEnabled(true);
tempAnimation.setFillAfter(true);
mimageView.startAnimation(tempAnimation);
So,the problem is that it is leaving behind a trail /previous positions for just a brief moment.But it doesnt look good or smooth.I have noticed that if I use only 1 animation it is fine but using the animation set causes the trail.Are there any tips to avoid this?
Cheers
Found the answer eventually at https://code.google.com/p/android/issues/detail?id=22151.
Scale and Translation Animations have a problem on Android 2.3 .The simplest way to fix this is to add a small transparent padding around the image.In the code shown above,Just add
mimageView.setPadding(1,1,1,1);
Works like a charm!
Alphaing a drawable work well like this:
if(mAlphaAnimation == null){
mAlphaAnimation = ObjectAnimator.ofFloat(this, "alpha", 0.0f,1.0f).setDuration(TARGET_ANIM_ALPHA_DURATION);
mAlphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
mAlphaAnimation.setStartDelay(TARGET_ANIM_ALPHA_DELAY_BASE*power);
mAlphaAnimation.setRepeatCount(ValueAnimator.INFINITE);
mAlphaAnimation.setRepeatMode(ValueAnimator.REVERSE);
mAlphaAnimation.addUpdateListener(this);
}
But if I want rotate a drawable like below , it don's work.
private void createRotateAnim(float fromDegress,float toDegress,int duration){
if(mRotateAnimation == null){
mRotateAnimation = ObjectAnimator.ofFloat(this, "rotation",fromDegress,toDegress).setDuration(duration);
mRotateAnimation.setStartDelay(100);
mRotateAnimation.setInterpolator(new AccelerateInterpolator());
mRotateAnimation.addUpdateListener(this);
}
}
Anyone can help me to fix this issue, or these is any other way to create a rotation drawable animation .
I am sorry to my poor English.
Try with ObjectAnimator instead.
ImageView imageview = (ImageView)findViewById(R.id.image);
ObjectAnimator imageViewObjectAnimator = ObjectAnimator.ofFloat(imageview ,
"rotation", 0f, 360f);
imageViewObjectAnimator.setDuration(1000); // miliseconds
imageViewObjectAnimator.start();
EDIT
Since this question draw some attention let me to explain why to use ObjectAnimator instead of other Transition animators
The thing about using ObjectAnimator is that it's moving both the visible and the clickable area of the item, if you use another animation method, for example Transition Animation or some other Animators, and let's say if you want to move the Button from the bottom left of the screen to the top left, it will only move the visible area but not the Button itself, the clickable area will still be on the previous position, in this case the clickable area will still be on the bottom left instead of the top left where you moved the button.
If you do the same with ObjectAnimator, both the visible area, and the clickable area will move the the desired location.
Try this simple Rotation Animation applied to a image.
ImageView imageview = (ImageView)findViewById(R.id.myimage);
RotateAnimation rotate = new RotateAnimation(180, 360, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(500);
imageview.startAnimation(rotate);
This answer is just for a sake of question, it is correct that Clickable area will be different than View's current position. Please check this question for making clickable area correct. Button is not clickable after TranslateAnimation
I have an xml with 12 image. for example 3*4 table, where each cell contains an image.
In the OnCreate I write animation every image:
AnimationSet set = new AnimationSet(true);
Animation animation = new TranslateAnimation(
Animation.ABSOLUTE, -300.0f, Animation.START_ON_FIRST_FRAME, 0.0f,
Animation.ABSOLUTE, -800.0f, Animation.START_ON_FIRST_FRAME, 0.0f);
animation.setFillBefore(true);
animation.setFillAfter(true);
animation.setFillEnabled(true);
animation.setDuration(5000);
I want to start the animation from the top left of the screen and to end the animation to real position. But the animation is only use the image or cell region. Is there any solution to the animation, use the whole screen?
If they're all under the same parent view, you can set the parent's clipChildren attribute to false, which would allow the animation to extend beyond its own constraints (as long as it still remains within the boundaries of its parent):
android:clipChildren="false"
I want to be able to do this: the TextView to change its size (to get bigger) and to change its alpha value (from invisible to become visible). All of this using Animation and have this changes happen at the same time.
For that purpose I come up with this code:
AnimationSet set = new AnimationSet(true);
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(2000);
animation.setStartOffset(300);
animation.setFillAfter(true);
set.addAnimation(animation);
animation = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f);
animation.setDuration(2000);
animation.setStartOffset(300);
animation.setFillAfter(true);
set.addAnimation(animation);
text.startAnimation(set);
The problem with this is that I want this transformation to remain. But the textView keeps coming back to its original size at the end. (But it remains visible - alpha = 1.0f). Am I doing something wrong? Please, if someone knows how can I make this work, help me. Thank u in advance!
I've found an answer for the problem five minutes after actually posting it. You should not define setFillAfter for the individual animations that you define in the animation set. You should only define setFillAfter ON the animation set itself