Animation up working. Animation back down not working - android

I have a menu I am trying to animate. I am splitting a menu by changing margins
and inserting a new menu. When I want to insert the menu, the animation is:
level3Height = level3Frame.getHeight();
final int newBottomMargin = (int)(origBottomMargin + level3Height/2);
final int newTopMargin = (int)(origTopMargin + level3Height/2);
splitUp = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) btnShopWireless.getLayoutParams();
params.bottomMargin = (int)(newBottomMargin * interpolatedTime);
btnShopWireless.setLayoutParams(params);
}
};
joinDown = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) btnShopWireless.getLayoutParams();
params.bottomMargin = (int)(origBottomMargin * interpolatedTime);
btnShopWireless.setLayoutParams(params);
}
};
splitUp.setDuration(1000);
splitUp.setInterpolator(new BounceInterpolator());
joinDown.setDuration(500);
joinDown.setInterpolator(new BounceInterpolator());
After getting the height of the inserted menu, the animation moves the Views upward very nicely:
btnShopWireless.startAnimation(splitUp);
All that works great! But....
When I want to remove the inserted level menu and move things back down I use the below, and the animation doesn't happen - the Views simply slam back into
their original place with no smooth motion.
btnShopWireless.startAnimation(joinDown);
I have AnimationListeners set up to setVisibility to VISIBLE onAnimationStart and also setVisibility to GONE onAnimationEnd. They are doing their job, so I know the animation is getting invoked or the visibility would never occur within the AnimationListeners for joinDown. But the animated movement backdown just never happens. I can only animate the first one, splitUp.
Anyone have any clues as to what I am missing in order to get the second animation working?

I figured out what my problem was - pure IQ underflow.
The originalMargin was 0. I increased them to about 190dp to fit in a 3rd menu. When it time to bring the menu together and remove the 3rd menu, the transformation used the original margins again multiplied by the time value. No matter how much time or which interpolator, the originalMargin*interpolatedTime would always be 0.
To fix it, I used this calculation:
joinDown = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) btnShopWireless.getLayoutParams();
params.bottomMargin = (int)(newBottomMargin -(level3Height/2 * interpolatedTime));
btnShopWireless.setLayoutParams(params);
}
};

Related

setDuration not working in Animation class

I'm trying to animate the height of a ConstraintLayout using the Animation class, and the setDuration method doesn't seem to be working. The height is just instantly changed to the desired height value. I've seen posts about animations being disabled in the developer options, but that's not the problem, it's set to 1x. Anyway, code is below:
public static void scaleUp() {
Animation animation = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) profileLayout.getLayoutParams();
// modify your layout params here
params.height = 10;
profileLayout.setLayoutParams(params);
}
};
animation.setDuration(300); // in ms
profileLayout.startAnimation(animation);
}
Instead of params.height = 10; use params.height = (int)(10.0 * interpolatedTime).
Append profileLayout.requestLayout(); at the end of your applyTransformation method. This is used to update the layout on a screen.
Possible Solutions:
Answered Here
Medium Article About Animating

ChangeBounds Android Transition

I have a recyclerview in my app, and each row contains a button which shows a text in the same cell, under the button. I have used ChangeBounds transition to make the text appear with a smooth animation, increasing the row height until the text is completely shown. So when a button is clicked, I do:
TransitionManager.beginDelayedTransition(row, transition)
holder.hiddenText.setVisibility(View.VISIBLE)
It works well, but whith a problem. The hidden text appears with an animation which increases its height, as expected. But the row height is not animated, and it jumps from the original height until the final height without any animation.
Is there any way to achieve a height transition over the row, to increase at the same time as the text?
If you want animation to take effect for row also, then you need to perform beginDelayedTransition() on a one layer higher of the row, which in your case maybe is the actual RecyclerView.
Try this on your row's layout
public static void expand(final View v) {
v.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
final int targetHeight = v.getMeasuredHeight();
// Older versions of android (pre API 21) cancel animations for views with a height of 0.
v.getLayoutParams().height = 1;
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? LayoutParams.WRAP_CONTENT
: (int)(targetHeight * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
// 1dp/ms
a.setDuration((int)(targetHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
Linear or Relative layout of row's will animate and expand. Hope this solves your problem

How to smoothen Linear layout height animation, having heavy content

Animation animation = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
ViewGroup.LayoutParams params = slidingPane.getLayoutParams();
int calculatedHeight = expandedHeight - ((int) (expandedHeight * interpolatedTime));
if (calculatedHeight <= collapsedHeight) {
calculatedHeight = collapsedHeight;
}
params.height = calculatedHeight;
slidingPane.setLayoutParams(params);
slidingPane.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
animation.setDuration(ANIMATION_DURATION);
animation.setAnimationListener(animationListener);
slidingPane.startAnimation(animation);
SlidingPane is a LinearLayout and it has a ListView as a child. ListView contains images in every row.
Now this code is working absolutely fine, but animation is not smooth. If I remove images from listview then it works fine.
I have already tried following things based on the answers on SO on similar questions -
1. Hide the content of sliding pane before animation and then again make them visible on animation end. It helps but behavior looks very odd
2. Set android:animateLayoutChanges="true" in xml, but its not animating anything
Is there anyway to solve this problem?
Instead of manually changing the height on each animation step, you should try to use the more systematic animation, like ValueAnimator, or ObjectAnimator:
slidingPane.animate().scaleY(0f).setInterpolator(new AccelerateDecelerateInterpolator()).setDuration(ANIMATION_DURATION);
You can use pivotY/pivotY on the view to control the anchor point of the scale animation.
Related docs:
https://developer.android.com/reference/android/animation/ValueAnimator.html
https://developer.android.com/reference/android/animation/ObjectAnimator.html
https://developer.android.com/guide/topics/graphics/prop-animation.html

View disappear after animating out of Screen bounds

I'm implementing an Animation for one menu in my project.
The animation itself is ok, the menu enters and exit just as I wanted: Slide from left to right and right to left, however...
If the entire view is OUT of the screen, then it NEVER comes back egain! If, at least one pixel is still inside the screen, then it comes back normally.
I belive that Android is disposing the layout, and not caring about it after out of the screen bounds. I tried to place a setVisibility(VISIBLE) but it also didn't worked.
Here is the code:
public class ChwaziMenuAnimation extends Animation{
float posStart = 0;
float posTarget = 100;
int getCurrentPosition(){
RelativeLayout.LayoutParams rootParam =
(RelativeLayout.LayoutParams) rootView.getLayoutParams();
return rootParam.leftMargin;
}
public void setTarget(float target){
// Save current position
posStart = getCurrentPosition();
posTarget = target;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
RelativeLayout.LayoutParams rootParam =
(RelativeLayout.LayoutParams) rootView.getLayoutParams();
// Calculate current position
rootParam.leftMargin = (int) ((posTarget - posStart) * interpolatedTime + posStart);
rootView.setLayoutParams(rootParam);
}
/*
* Since we will be animating the margin, the bounds will always change
*/
public boolean willChangeBounds() {
return true;
};
};
And how I initialize the animation:
public void appear(){
Log.i(TAG, "appear");
menuAnimation.setTarget(0);
menuAnimation.setDuration(750);
rootView.clearAnimation();
rootView.startAnimation(menuAnimation);
}
public void disapear(){
Log.i(TAG, "disapear");
menuAnimation.setTarget(-400);
menuAnimation.setDuration(750);
rootView.startAnimation(menuAnimation);
}
I encountered the same problem, my workaround so far is to extend the view bounds to at least one pixel on the displayable area, and make that part transparent. Ugly, but for me it seems to work.
To make it even more weird: the view did not disappear, when shifted out the right side of the screen, only when shifted out the left side of the screen. But that might be device dependent.

Create Android animation softly

I have a LinearLayout (called layout) with height as fill_parent and an initial top margin of 200dp inside a RelativeLayout.
When I clicked a button, I want the topMargin to become 0, expanding the LinearLayout.
I am using the next code:
final RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT);
Animation animation = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
int topMargin = (int)((1-interpolatedTime)*200);
layoutParams.setMargins(0, topMargin, 0, 0);
layout.setLayoutParams(layoutParams);
LogThis.debug("topMargin: "+topMargin);
}
};
animation.setDuration(1000);
layout.startAnimation(animation);
The problem is that although it makes an animation, it is not soft. It does the transformation in 4 steps, so it does not look good.
Do you have any idea how to make this kind of transformation softly?
Thank you in advance.
EDIT
I have this in the first moment:
And after the animation I want this:
With the TranslationAnimation I get this:
the choppy animation is happening because that's not how the Animation are supposed to be used. Those are to be use Transformation object passed onto the method.
But because you're using a simple translation you can easily achieve that using a TranslateAnimation like on this answer:
translate animation

Categories

Resources