Objectanimator Animate Linearlayout Width

Android property animation: how to increase view height?

ValueAnimator anim = ValueAnimator.ofInt(viewToIncreaseHeight.getMeasuredHeight(), -100);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = viewToIncreaseHeight.getLayoutParams();
layoutParams.height = val;
viewToIncreaseHeight.setLayoutParams(layoutParams);
}
});
anim.setDuration(DURATION);
anim.start();

How to animate the width and height of a Layout?

Sure that is possible.

Simply write your own custom-animation and modify the LayoutParams of your animated view.
In this example, the animation animates the height of the animated View. Of course, animating the width is also possible.

This is how it could look like:

public class ResizeAnimation extends Animation {

private int startHeight;
private int deltaHeight; // distance between start and end height
private View view;

/**
* constructor, do not forget to use the setParams(int, int) method before
* starting the animation
* @param v
*/
public ResizeAnimation (View v) {
this.view = v;
}

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {

view.getLayoutParams().height = (int) (startHeight + deltaHeight * interpolatedTime);
view.requestLayout();
}

/**
* set the starting and ending height for the resize animation
* starting height is usually the views current height, the end height is the height
* we want to reach after the animation is completed
* @param start height in pixels
* @param end height in pixels
*/
public void setParams(int start, int end) {

this.startHeight = start;
deltaHeight = end - startHeight;
}

/**
* set the duration for the hideshowanimation
*/
@Override
public void setDuration(long durationMillis) {
super.setDuration(durationMillis);
}

@Override
public boolean willChangeBounds() {
return true;
}
}

In code, create a new Animation and apply it to the RelativeLayout that you want to animate:

RelativeLayout relativeLayout = (RelativeLayout) ((LinearLayout) view.findViewById(viewId)).getParent();

// getting the layoutparams might differ in your application, it depends on the parent layout
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams();

ResizeAnimation a = new ResizeAnimation(relativeLayout);
a.setDuration(500);

// set the starting height (the current height) and the new height that the view should have after the animation
a.setParams(lp.height, newHeight);

relativeLayout.startAnimation(a);

Animating weightSum property using ObjectAnimator

I was right in the sense that I need to update the layout myself:

float ws = mDualPane.getWeightSum();
ObjectAnimator anim = ObjectAnimator.ofFloat(mDualPane, "weightSum", ws, 2.0f);
anim.setDuration(5000);
anim.addUpdateListener(this);
anim.start();

Now, I added an UpdateListener to the ObjectAnimator, which is implemented by my Activity and updates the layout:

@Override
public void onAnimationUpdate(ValueAnimator animation) {
mDualPane.requestLayout();
}

It seems strange to me, that ObjectAnimator doesn't call this itself, but anyway, this is how to get it working.

The solution is especially nice, in my opinion, since you can very nicely animate layouts sliding in, independent of screensize...

How does one Animate Layout properties of ViewGroups?

Since noone helped you yet and my first answer was such a mess I'll try to give you the right answer this time ;-)

Actually I like the idea and I think this is a great visual effect which might be useful for a bunch of people. I would implement an overflow of the right view (I think the shrink looks strange since the text is expanding to the bottom).

But anyway, here's the code which works perfectly fine (you can even toggle while it's animating).

Quick explanation:

You call toggle with a boolean for your direction and this will start a handler animation call loop. This will increase or decrease the weights of both views based on the direction and the past time (for a smooth calculation and animation). The animation call loop will invoke itself as long it hasn't reached the start or end position.

The layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="10"
android:id="@+id/slide_layout">
<TextView
android:layout_weight="7"
android:padding="10dip"
android:id="@+id/left"
android:layout_width="0dip"
android:layout_height="fill_parent"></TextView>
<TextView
android:layout_weight="3"
android:padding="10dip"
android:id="@+id/right"
android:layout_width="0dip"
android:layout_height="fill_parent"></TextView>
</LinearLayout>

The activity:

public class TestActivity extends Activity {

private static final int ANIMATION_DURATION = 1000;

private View mSlidingLayout;
private View mLeftView;
private View mRightView;

private boolean mAnimating = false;
private boolean mLeftExpand = true;
private float mLeftStartWeight;
private float mLayoutWeightSum;
private Handler mAnimationHandler = new Handler();
private long mAnimationTime;

private Runnable mAnimationStep = new Runnable() {
@Override
public void run() {
long currentTime = System.currentTimeMillis();
float animationStep = (currentTime - mAnimationTime) * 1f / ANIMATION_DURATION;
float weightOffset = animationStep * (mLayoutWeightSum - mLeftStartWeight);

LinearLayout.LayoutParams leftParams = (LinearLayout.LayoutParams)
mLeftView.getLayoutParams();
LinearLayout.LayoutParams rightParams = (LinearLayout.LayoutParams)
mRightView.getLayoutParams();

leftParams.weight += mLeftExpand ? weightOffset : -weightOffset;
rightParams.weight += mLeftExpand ? -weightOffset : weightOffset;

if (leftParams.weight >= mLayoutWeightSum) {
mAnimating = false;
leftParams.weight = mLayoutWeightSum;
rightParams.weight = 0;
} else if (leftParams.weight <= mLeftStartWeight) {
mAnimating = false;
leftParams.weight = mLeftStartWeight;
rightParams.weight = mLayoutWeightSum - mLeftStartWeight;
}

mSlidingLayout.requestLayout();

mAnimationTime = currentTime;

if (mAnimating) {
mAnimationHandler.postDelayed(mAnimationStep, 30);
}
}
};

private void toggleExpand(boolean expand) {
mLeftExpand = expand;

if (!mAnimating) {
mAnimating = true;
mAnimationTime = System.currentTimeMillis();
mAnimationHandler.postDelayed(mAnimationStep, 30);
}
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.slide_test);

mLeftView = findViewById(R.id.left);
mRightView = findViewById(R.id.right);
mSlidingLayout = findViewById(R.id.slide_layout);

mLeftStartWeight = ((LinearLayout.LayoutParams)
mLeftView.getLayoutParams()).weight;
mLayoutWeightSum = ((LinearLayout) mSlidingLayout).getWeightSum();
}
}

How to animate to wrap_content?

You can do something like this. Pass a view that is set initially to gone.

public static void expand(final View view) {
view.measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
final int targetHeight = view.getMeasuredHeight();

// Set initial height to 0 and show the view
view.getLayoutParams().height = 0;
view.setVisibility(View.VISIBLE);

ValueAnimator anim = ValueAnimator.ofInt(view.getMeasuredHeight(), targetHeight);
anim.setInterpolator(new AccelerateInterpolator());
anim.setDuration(1000);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = (int) (targetHeight * animation.getAnimatedFraction());
view.setLayoutParams(layoutParams);
}
});
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
// At the end of animation, set the height to wrap content
// This fix is for long views that are not shown on screen
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
}
});
anim.start();
}


Related Topics



Leave a reply



Submit