Android animations - Translate and Scale don't work properly - android

I made a little method to translate a view above another view and scale to that view's size.
Method works, but it translate the view with a margin.
This is the method:
public AnimationSet getFromToAnimation(View from, View to, final Runnable onEnd){
AnimationSet animationSet = new AnimationSet(true);
animationSet.setInterpolator(new AccelerateDecelerateInterpolator());
animationSet.setFillEnabled(true);
animationSet.setDuration(3000);
LinearLayout.LayoutParams fromParams = (LinearLayout.LayoutParams) from.getLayoutParams();
LinearLayout.LayoutParams toParams = (LinearLayout.LayoutParams) to.getLayoutParams();
float tx = (to.getX() + toParams.leftMargin) - (from.getX() + fromParams.leftMargin);
float ty = (to.getY() + toParams.topMargin) - (from.getY() + fromParams.topMargin);
TranslateAnimation translateAnimation = new TranslateAnimation(0, tx,0, ty);
float x = (float) to.getWidth() / (float) from.getWidth();
float y = (float) to.getHeight() / (float) from.getHeight();
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, x, 1f, y,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
animationSet.addAnimation(translateAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
onEnd.run();
}
#Override
public void onAnimationRepeat(Animation animation) {}
});
return animationSet;
}
Then I use it like this
LinearLayout lnrFrom = findViewById(R.id.lnr_game_operation);
LinearLayout lnrTo = findViewById(R.id.lnr_game_operation_old);
AnimationSet animation = getFromToAnimation(lnrFrom, lnrTo, new Runnable() {
#Override
public void run() {
...
}
});
lnrFrom.startAnimation(animation);
And this is xml with many layouts, which I need to start the animation
<LinearLayout
android:gravity="center"
android:orientation="vertical"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/lnr_game_operation_old"
android:background="#drawable/operation"
android:gravity="center"
android:orientation="horizontal"
android:layout_width="#dimen/dp100"
android:layout_height="#dimen/dp60">...</LinearLayout>
<LinearLayout
android:id="#+id/lnr_game_operation"
android:background="#drawable/operation"
android:gravity="center"
android:orientation="horizontal"
android:layout_width="#dimen/dp120"
android:layout_height="#dimen/dp70">...</LinearLayout>
<LinearLayout
android:id="#+id/lnr_game_operation_new"
android:visibility="invisible"
android:background="#drawable/operation"
android:gravity="center"
android:orientation="horizontal"
android:layout_width="#dimen/dp100"
android:layout_height="#dimen/dp60">...</LinearLayout>
</LinearLayout>
Does anyone know another method to do this or why it doesn't work?

Related

Using TranslateAnimation to an item (from a ListView) doesn't takeout his parent

I'm trying to use TranslateAnimation to move a profile picture to the top when item is clicked.
I found the correct position (x, y) but the profile picture doesn't come out of his item area.
I tried to use bringToFront() method but it doesn't work.
My problem here
Code to animate my view
public void animateContactAdding(View view) {
View profileImage = view.findViewById(R.id.linear_layout_image_profile);
int positionViewContact[] = {0, 0};
profileImage.getLocationOnScreen(positionViewContact);
int positionHeader[] = {0, 0};
mRelativeLayoutContactHeader.getLocationOnScreen(positionHeader);
float distanceBtwViews = (positionViewContact[1] - positionHeader[1]) * -1;
TranslateAnimation anim = new TranslateAnimation(0, 0, 0, distanceBtwViews);
anim.setDuration(400);
anim.setAnimationListener(new TranslateAnimation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
});
profileImage.startAnimation(anim);
}
Item
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight">
<LinearLayout
android:id="#+id/linear_layout_image_profile"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/circle_image_placeholder"
android:layout_width="?android:attr/listPreferredItemHeight"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="10dp" />
<ImageView
android:id="#+id/circle_image_profile"
android:layout_width="?android:attr/listPreferredItemHeight"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="10dp" />
</LinearLayout>
<TextView
android:id="#android:id/text2"
android:layout_width="match_parent"
android:layout_height="26dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_toEndOf="#+id/linear_layout_image_profile"
android:ellipsize="marquee"
android:lines="1"
android:visibility="gone" />
<TextView
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#android:id/text2"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:layout_toEndOf="#+id/linear_layout_image_profile"
android:ellipsize="marquee"
android:gravity="center_vertical"
android:lines="1"
android:textAppearance="#style/TextAppearance.RalewaySemiBold"
android:textSize="17sp" />
</RelativeLayout>
Probably you are animating a entire layout. Try to apply the animation only on ImageView and see what happens:
public void animateContactAdding(View view) {
int positionViewContact[] = {0, 0};
profileImage.getLocationOnScreen(positionViewContact);
int positionHeader[] = {0, 0};
mRelativeLayoutContactHeader.getLocationOnScreen(positionHeader);
float distanceBtwViews = (positionViewContact[1] - positionHeader[1]) * -1;
TranslateAnimation anim = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF, 0.0F,
Animation.RELATIVE_TO_SELF, 2.0F, Animation.RELATIVE_TO_SELF, 0.0F
);
anim.setDuration(2000);
anim.setFillAfter(true);
anim.setAnimationListener(new TranslateAnimation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
});
view.startAnimation(anim);
}

Animate a view from one Layout to other Layout

Check attached image for easy explanation.
Translate animation works but it animates inside the same view.
I want view to fly out from one layout to other.
I tried this from another answer here. (Animates in same layout)
public class Animations {
public Animation fromAtoB(float fromX, float fromY, float toX, float toY, int speed){
Animation fromAtoB = new TranslateAnimation(
Animation.ABSOLUTE, //from xType
fromX,
Animation.ABSOLUTE, //to xType
toX,
Animation.ABSOLUTE, //from yType
fromY,
Animation.ABSOLUTE, //to yType
toY
);
fromAtoB.setDuration(speed);
fromAtoB.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
return fromAtoB;
}
I recently did animation of a similar kind using Animators. In general, views will not display themselves outside of their parents' boundaries, the view will be cut by it's parent's boundaries. That's why, the trick is to place a new view (shuttleView) on top of the origin view (fromView) that you want to animate, align them, and animate scaling/translation of shuttleView into a target view (toView).
This solution supports both scaling and translation, here is sample: https://www.dropbox.com/s/iom95o93076h52f/device-2016-06-03-111557.mp4?dl=0
Here is the code:
activity_main.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_alignParentTop="true"
android:background="#android:color/holo_blue_dark">
<TextView
android:id="#+id/itemTo"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="10dp"
android:background="#android:color/holo_blue_bright"
android:text="to"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_alignParentBottom="true"
android:background="#android:color/holo_blue_dark">
<TextView
android:layout_width="90dp"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="#android:color/holo_blue_bright" />
<TextView
android:id="#+id/itemFrom"
android:layout_width="90dp"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:text="from"
android:background="#android:color/holo_blue_bright" />
<TextView
android:layout_width="90dp"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="#android:color/holo_blue_bright" />
</LinearLayout>
<View
android:id="#+id/shuttle"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_blue_bright"/>
Activity class:
public class MainActivity extends AppCompatActivity {
public static final int ANIMATION_SPEED = 3000;
private RelativeLayout rootView;
private View fromView, toView, shuttleView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rootView = (RelativeLayout) findViewById(R.id.rootView);
fromView = findViewById(R.id.itemFrom);
toView = findViewById(R.id.itemTo);
shuttleView = findViewById(R.id.shuttle);
fromView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Rect fromRect = new Rect();
Rect toRect = new Rect();
fromView.getGlobalVisibleRect(fromRect);
toView.getGlobalVisibleRect(toRect);
AnimatorSet animatorSet = getViewToViewScalingAnimator(rootView, shuttleView, fromRect, toRect, ANIMATION_SPEED, 0);
animatorSet.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
shuttleView.setVisibility(View.VISIBLE);
fromView.setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationEnd(Animator animation) {
shuttleView.setVisibility(View.GONE);
fromView.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
animatorSet.start();
}
});
}
public static AnimatorSet getViewToViewScalingAnimator(final RelativeLayout parentView,
final View viewToAnimate,
final Rect fromViewRect,
final Rect toViewRect,
final long duration,
final long startDelay) {
// get all coordinates at once
final Rect parentViewRect = new Rect(), viewToAnimateRect = new Rect();
parentView.getGlobalVisibleRect(parentViewRect);
viewToAnimate.getGlobalVisibleRect(viewToAnimateRect);
viewToAnimate.setScaleX(1f);
viewToAnimate.setScaleY(1f);
// rescaling of the object on X-axis
final ValueAnimator valueAnimatorWidth = ValueAnimator.ofInt(fromViewRect.width(), toViewRect.width());
valueAnimatorWidth.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
// Get animated width value update
int newWidth = (int) valueAnimatorWidth.getAnimatedValue();
// Get and update LayoutParams of the animated view
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewToAnimate.getLayoutParams();
lp.width = newWidth;
viewToAnimate.setLayoutParams(lp);
}
});
// rescaling of the object on Y-axis
final ValueAnimator valueAnimatorHeight = ValueAnimator.ofInt(fromViewRect.height(), toViewRect.height());
valueAnimatorHeight.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
// Get animated width value update
int newHeight = (int) valueAnimatorHeight.getAnimatedValue();
// Get and update LayoutParams of the animated view
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewToAnimate.getLayoutParams();
lp.height = newHeight;
viewToAnimate.setLayoutParams(lp);
}
});
// moving of the object on X-axis
ObjectAnimator translateAnimatorX = ObjectAnimator.ofFloat(viewToAnimate, "X", fromViewRect.left - parentViewRect.left, toViewRect.left - parentViewRect.left);
// moving of the object on Y-axis
ObjectAnimator translateAnimatorY = ObjectAnimator.ofFloat(viewToAnimate, "Y", fromViewRect.top - parentViewRect.top, toViewRect.top - parentViewRect.top);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setInterpolator(new DecelerateInterpolator(1f));
animatorSet.setDuration(duration); // can be decoupled for each animator separately
animatorSet.setStartDelay(startDelay); // can be decoupled for each animator separately
animatorSet.playTogether(valueAnimatorWidth, valueAnimatorHeight, translateAnimatorX, translateAnimatorY);
return animatorSet;
}
}
You can do a whole bunch of customizations in terms of what appears and disappears at different stages of animation in animatorSet listener. Hope it's helpful.
If someone is looking for simpler solution, you can use transitions framework:
https://developer.android.com/training/transitions/index.html
To animate translation from one parent view to another, there is special transition ChangeTransform:
https://developer.android.com/reference/android/transition/ChangeTransform.html
And a small example:
animatedView = View.inflate(ActivityMain.this, R.layout.item, firstParent);
animatedView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
Transition move = new ChangeTransform()
.addTarget(animatedView)
.setDuration(2000));
TransitionManager.beginDelayedTransition(rootParent, move);
firstParent.removeView(animatedView);
animatedView.setPadding(2,2,2,2);
animatedView.setElevation(4);
secondParent.addView(animatedView, 0);

Android: How to keep Animation after Animation

I'm implementing animation when slide between fragments in ViewPager.
when slide to new fragment I want to scale the view and the make start a set of animation includes alpha and translate animation but when start the set problem is scale animation's result was not keeping (the view return to the original size).
I had tried to with
scaleAnimation.setFillAfter(true);
scaleAnimation.setFillEnabled(true);
But it just work when I do not start set of animation above, When I start the set, the view is return to original size.
Any body can give me a solution?
EDIT:
First thing I want to scale an imageView by animation:
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, 1.3f, 1f, 1.3f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 1);
scaleAnimation.setDuration(1000);
scaleAnimation.setFillAfter(true);
scaleAnimation.setFillEnabled(true);
Then I want after scale, ImageView still keep new scale size and start another Animation as:
private void startSetAnimation() {
AnimationSet set = new AnimationSet(true);
set.setDuration(3000);
set.setFillAfter(true);
float alphaS = 1f;
AlphaAnimation alpha = new AlphaAnimation(currentAlpha, alphaS);
alpha.setDuration(3000);
alpha.setFillAfter(true);
float scale = 0.1f;
TranslateAnimation translate = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, currentTrans,
Animation.RELATIVE_TO_SELF, scale,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF , 0f);
translate.setFillAfter(true);
translate.setDuration(3000);
set.addAnimation(translate);
set.addAnimation(alpha);
ivHorizontal.startAnimation(set);
}
So I add below code to scale animation to make it but not success.
scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
startSetAnimation();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
ivHorizontal.startAnimation(scaleAnimation);
There is an onAnimationEnd listener you can utilize kick off certain animations when other ones are done. I'll post code when I get to my computer
Edit:
The reason why your imageView doesn't retain its new size after scaling is because Animations aren't permanent, what you need to do is this
scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
// change the actual width and height so it doesn't go back to what it was
LayoutParams layoutParams = (LayoutParmas) ivHorizontal.getLayoutParams();
layoutParams.width = ivHorizental.getWidth();
layoutParams.height= ivHorizental.getHeight();
ivHorizontal.setLayoutParams(layoutParams);
ivHorizontal.requestLayout();
startSetAnimation();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
ivHorizontal.startAnimation(scaleAnimation);

How to animate 2 layouts with margins from top to bottom and from bottom to top

I'm trying to create an app that has 2 layouts: one on top and one on bottom. I want that when you click on a layout, 2 change of position and one climb and the other lower.
But I have several problems:
layout 2 disturbs their position
2 layouts will disappear from the screen before putting on
How can I fix my mistakes? Thank you
MainActivity.java
public class MainActivity extends Activity {
RelativeLayout rl_footer, rl_footer2;
ImageView iv_header, iv_header2;
boolean isBottom = true;
Button btn1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rl_footer = (RelativeLayout) findViewById(R.id.rl_footer);
rl_footer2 = (RelativeLayout) findViewById(R.id.rl_footer2);
iv_header = (ImageView) findViewById(R.id.iv_up_arrow);
iv_header2 = (ImageView) findViewById(R.id.iv_up_arrow2);
iv_header.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (isBottom) {
SlideToAbove1();
SlideToDown2();
isBottom = false;
} else {
SlideToDown1();
SlideToAbove2();
isBottom = true;
}
}
});
}
public void SlideToAbove1() {
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, -5.0f);
slide.setDuration(600);
slide.setFillAfter(true);
slide.setFillEnabled(true);
rl_footer.startAnimation(slide);
slide.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
rl_footer.clearAnimation();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
rl_footer.getWidth(), rl_footer.getHeight());
lp.setMargins(20, 20, 0, 0);
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
rl_footer.setLayoutParams(lp);
}
});
}
public void SlideToAbove2() {
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, -5.0f);
slide.setDuration(600);
slide.setFillAfter(true);
slide.setFillEnabled(true);
rl_footer2.startAnimation(slide);
slide.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
rl_footer2.clearAnimation();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
rl_footer2.getWidth(), rl_footer2.getHeight());
lp.setMargins(0, 20, 20, 0);
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP | RelativeLayout.ALIGN_PARENT_RIGHT);
rl_footer2.setLayoutParams(lp);
}
});
}
public void SlideToDown1() {
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, 5.2f);
slide.setDuration(600);
slide.setFillAfter(true);
slide.setFillEnabled(true);
rl_footer.startAnimation(slide);
slide.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
rl_footer.clearAnimation();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
rl_footer.getWidth(), rl_footer.getHeight());
lp.setMargins(20, 0, 0, 20);
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
rl_footer.setLayoutParams(lp);
}
});
}
public void SlideToDown2() {
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, 5.2f);
slide.setDuration(600);
slide.setFillAfter(true);
slide.setFillEnabled(true);
rl_footer2.startAnimation(slide);
slide.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
rl_footer2.clearAnimation();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
rl_footer2.getWidth(), rl_footer2.getHeight());
lp.setMargins(0, 0, 20, 20);
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM | RelativeLayout.ALIGN_PARENT_RIGHT);
rl_footer2.setLayoutParams(lp);
}
});
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rl_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000" >
<RelativeLayout
android:id="#+id/rl_footer"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_alignParentTop="true"
android:layout_margin="20dp"
android:background="#666666" >
<ImageView
android:id="#+id/iv_up_arrow"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:background="#000000" />
<TextView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:gravity="center"
android:text="1"
android:textColor="#FFFFFF"
android:textSize="30sp" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/rl_footer2"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_margin="20dp"
android:background="#666666" >
<ImageView
android:id="#+id/iv_up_arrow2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:background="#FFFFFF" />
<TextView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:gravity="center"
android:text="2"
android:textColor="#000000"
android:textSize="30sp" />
</RelativeLayout>
</RelativeLayout>
I've developed an animation subclass to do this exact thing. Here's the code:
public class MarginAnimation extends Animation
{
private View mView;
private int mTargetTopMargin;
private int mTargetLeftMargin;
private int mStartTopMargin;
private int mStartLeftMargin;
public MarginAnimation(View view, int targetTopMargin, int targetLeftMargin)
{
mView = view;
mTargetTopMargin = targetTopMargin;
mTargetLeftMargin = targetLeftMargin;
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)mView.getLayoutParams();
mStartTopMargin = params.topMargin;
mStartLeftMargin = params.leftMargin;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t)
{
// I assume the view is inside a RelativeLayout. Change as required.
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)mView.getLayoutParams();
params.topMargin = (int)(mStartTopMargin + (mTargetTopMargin - mStartTopMargin) * interpolatedTime);
params.leftMargin = (int)(mStartLeftMargin + (mTargetLeftMargin - mStartLeftMargin) * interpolatedTime);
mView.setLayoutParams(params);
}
#Override
public boolean willChangeBounds()
{
return true;
}
}
Usage:
MarginAnimation animation = new MarginAnimation(view, targetTopMargin, targetLeftMargin);
view.startAnimation(animation);
I should note that animations which invoke layout changes aren't the most optimal choice in Android when it come to performance, but it should get the job done.
If you can, try performing an animation on translationX/Y and perform layout (margin) changes only in the beginning / end of the animation.

how to change a height layout as animation (programmatically)

how to change a height layout programatically as animation?
first :
after :
Heey Amigo,
After testing my code, i saw a small issue. Because i used "scaleY" it just "stretches" the view. That means if there is some text or something in the view, it will just stretch it and won't look nice. Try with the ValueAnimator instead, its works more smooth
public void onClick(View v)
{
if(!isBig){
ValueAnimator va = ValueAnimator.ofInt(100, 200);
va.setDuration(400);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
v.getLayoutParams().height = value.intValue();
v.requestLayout();
}
});
va.start();
isBig = true;
}
else{
ValueAnimator va = ValueAnimator.ofInt(200, 100);
va.setDuration(400);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
v.getLayoutParams().height = value.intValue();
v.requestLayout();
}
});
va.start();
isBig = false;
}
}
The XML:
<RelativeLayout
android:layout_width="150dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:background="#android:color/holo_red_dark"
android:onClick="onButtonClick"
android:clickable="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="My Layout"/>
</RelativeLayout>
Old Answer
You can use the ObjectAnimator, just remeber to set the pivotY(0) so it only moves on the bottom. Play with it yourself to match it your needs :)
private boolean isBig = false;
...
public void onClick(View v)
{
v.setPivotY(0f);
if(!isBig){
ObjectAnimator scaleY = ObjectAnimator.ofFloat(v, "scaleY", 2f);
scaleY.setInterpolator(new DecelerateInterpolator());
scaleY.start();
isBig = true;
}
else{
ObjectAnimator scaleY = ObjectAnimator.ofFloat(v, "scaleY", 1f);
scaleY.setInterpolator(new DecelerateInterpolator());
scaleY.start();
isBig = false;
}
}

Categories

Resources