ObjectAnimator animate LinearLayout width
Asked Answered
D

5

54

Ok, so i checked out http://android-developers.blogspot.com/2011/02/animation-in-honeycomb.html

He says you can animate the property of an object in a given time. And i tried moving around objects and it looks fine. I encountered a problem when i went changing the width of a LinearLayout. I got this:

10-26 14:51:27.190: E/PropertyValuesHolder(12681): Couldn't find setter/getter for       property width with value type float

Then i tried extending LinearLayout, with "myWidth"

public void setMyWidth(int myWidth) {
    LinearLayout.LayoutParams params = (LayoutParams) getLayoutParams();
    params.weight = myWidth;
    setLayoutParams(params);
    requestLayout();
    this.myWidth = myWidth;
}

No luck. Then i tried changing LayoutParams.width, turns out width and height are the only public properties in java history, and ObjectAnimator needs getter and setter. No luck. I'm embarassed to say i tried extending LayoutParams too... with no luck ofc.

Anybody succeded doing such a thing? I used old android.view.animation and i got what i wanted, but i'm curious for the future.

Dalia answered 26/10, 2011 at 13:3 Comment(1)
Unfortunately, I have a similar issue. Instead of animating the width, I tried animating the weightSum (which DOES have a getter/setter) to achieve the same effect. Maybe you can try something similar to achieve what you want, but I can't get it to work: #8342245. I'll keep you posted if I have some resultsMaddis
S
140

In situations where there isn't a simple property getter/setter you should use ValueAnimator and perform the animation manually.

Assuming:

  • v is the view you're animating
  • END_WIDTH is the target width of the view in pixels.
  • DURATION is the desired length of the animation in milliseconds.

Your code should look something like this:

    ValueAnimator anim = ValueAnimator.ofInt(v.getMeasuredWidth(), END_WIDTH);
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            int val = (Integer) valueAnimator.getAnimatedValue();
            ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
            layoutParams.width = val;
            v.setLayoutParams(layoutParams);
        }
    });
    anim.setDuration(DURATION);
    anim.start(); 
Stereograph answered 3/5, 2013 at 8:56 Comment(1)
END_WIDTH ? Well I've already have this view inflated, in my xml layout it has match_content (0dp for constraint layout), so why I have to set it programmatically? Animation should be from 0px to size set in layoutBillie
B
22

For what it's worth this works. After you change the width on the layout params you have to reset the layout params object.

private class WidthEvaluator extends IntEvaluator {

    private View v;
    public WidthEvaluator(View v) {
        this.v = v;
    }

    @Override
    public Object evaluate(float fraction, Object startValue, Object endValue) {
        int num = (Integer)super.evaluate(fraction, startValue, endValue);
        ViewGroup.LayoutParams params = v.getLayoutParams();
        params.width = num;
        v.setLayoutParams(params);
        return num;
    }
}

// your client code
ValueAnimator.ofObject(new WidthEvaluator(box), box.getWidth(), v.getWidth()).start();
Brucie answered 1/2, 2012 at 2:56 Comment(4)
To make this work with nineOldAndroids, change the evaluate method signature to use Integer instead of Object. public Integer evaluate(float fraction, Integer startValue, Integer endValue)Allotment
Don't use evaluators to perform view changes. Add an AnimatorUpdateListener instead.Apelles
@BraisGabin so what would be the correct call?Coextend
add a listener and do it thereApelles
N
7

I've created a small library ViewPropertyObjectAnimator that can do that in a very simple way (and uses a similar approach to this proposed by Tomer Weller).

You could achieve this animation with (assuming the mLinearLayout is the animated View and mEndWidth is the end value of the View's width):

ViewPropertyObjectAnimator.animate(mLinearLayout).width(mEndWidth).start();
Nath answered 15/10, 2015 at 10:38 Comment(0)
L
6

You have made a mistake

 params.weight = myWidth;

I think it is params.width not params.weight

Lilian answered 18/10, 2013 at 7:7 Comment(0)
W
0

I think a better way to accomplish this would be to use View's scaleX and scaleY property which are defined all the way down in View class, so it would be valid with practically any view or layout.

For example, consider this

ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(MyLinearLayout,"scaleX",0f,1f);
objectAnimator.setDuration(300);
objectAnimator.start();

It works.

Webb answered 24/6, 2015 at 12:41 Comment(2)
No, it does not work. This scales, i.e. stretches, the view, which is way different from just enlarging it, keeping intact the proportions of the view's contents.Neel
it just stretches view from the center but I need from leftBillie

© 2022 - 2024 — McMap. All rights reserved.