8

I develop a widget based on ViewGroup and my problem is that I need to save position of items after the end of animation. I called setFillAfter(true) in my animation object I created AnimationListener and in it's onAnimationEnd method call View.layout(l,t,r,b) to set the position after animation, because I want animation to start from new item's position next time. But in this case it looks like items are layouted twice. If I don't use View.layout(l,t,r,b) at the end of animation, next animation starts from previous position. Here is my code:

private void scrollUp() {
    for(int i = 0; i < getChildCount(); i++) {
        final View child = getChildAt(i);
        final int index = i; 
        final int newleft = child.getLeft() + mOffsetBetweenItems;
        final int newTop = child.getTop() - mOffsetBetweenItems;
        TranslateAnimation scrollUp = new TranslateAnimation(0, mOffsetBetweenItems, 0, -mOffsetBetweenItems);          
        scrollUp.setDuration(1500);
        scrollUp.setFillAfter(true);        
        scrollUp.setAnimationListener(
            new AnimationListener() {

                @Override
                public void onAnimationStart(Animation animation) {}

                @Override
                public void onAnimationRepeat(Animation animation) {}

                @Override
                public void onAnimationEnd(Animation animation) {
                    child.layout(newleft, newTop, newleft + child.getMeasuredWidth(), newTop + child.getMeasuredHeight() );
                }
            }
        );

        child.startAnimation(scrollUp);
    }
}

Please give me an advice how should I reset view's position accordingly to the end position of animation?

teoREtik
  • 7,886
  • 15
  • 46
  • 65

3 Answers3

20

You must use ObjectAnimator , it works from API 11 level . It changes View position automatic,

here is the example

ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(mContent_container, "translationX", startX, endX);
objectAnimator.setDuration(1000);
objectAnimator.start();

Thanks JUL for his answer

If your app not found object animator, change the API level from Project -> properties -> Android , than import android.animation.ObjectAnimator;

Community
  • 1
  • 1
Hayk Nahapetyan
  • 4,452
  • 8
  • 42
  • 61
12

I did it. Here is the code:

private void scrollUp() {
    for(int i = 0; i < getChildCount(); i++) {
        final View child = getChildAt(i);
        final int index = i; 
        final int newleft = child.getLeft() + mOffsetBetweenItems;
        final int newTop = child.getTop() - mOffsetBetweenItems;
        TranslateAnimation scrollUp = new TranslateAnimation(0, mOffsetBetweenItems, 0, -mOffsetBetweenItems);          
        scrollUp.setDuration(1500);
        scrollUp.setFillEnabled(true);        
        scrollUp.setAnimationListener(
            new AnimationListener() {

                @Override
                public void onAnimationStart(Animation animation) {}

                @Override
                public void onAnimationRepeat(Animation animation) {}

                @Override
                public void onAnimationEnd(Animation animation) {
                    child.layout(newleft, newTop, newleft + child.getMeasuredWidth(), newTop + child.getMeasuredHeight() );
                }
            }
        );

        child.startAnimation(scrollUp);
    }
}

Just removed setFillAfter(true) and write setFillEnabled(true) instead of. But in this case I don't understand the logic of setFillEnabled() working, because it provides behavior not like describes in documentation.

teoREtik
  • 7,886
  • 15
  • 46
  • 65
  • Setting the new left in onAnimationEnd fixed my issues. Thanks. In your code, at what point would mOffsetBetweenItems be set/updated? – speedynomads Jul 19 '13 at 08:39
  • Note: Doesn't work on Lollipop at least (guessing at some API level it was incidentally implemented as above, but doesn't work at least on Lollipop for sure) – DragonJawad Sep 27 '15 at 09:52
0

Reverse your animation; Start by giving your view a new position and then animate from the old position to the new position.

Jave
  • 31,598
  • 14
  • 77
  • 90
  • If I give a new position firstly, it's immidiately redrawing my view in new position – teoREtik Dec 13 '11 at 13:20
  • Not if you call startAnimation() as soon as you have changed the position. – Jave Dec 13 '11 at 13:22
  • If I call `View.layout()` before `view.startAnimation()` it redraws my view and animation starts from new position – teoREtik Dec 13 '11 at 13:23
  • Ah, but there are other ways to reposition your view than calling `View.layout()`. Personally I tend to modify the LayoutParams owned by the view. – Jave Dec 13 '11 at 13:31
  • `LayoutParams` just allow you to point new width and height, but I need to point also left and top coordinates – teoREtik Dec 13 '11 at 13:32
  • If you have a layout like `FrameLayout`, you van use the topMargin and leftMargin values to define an offset from the top left corner. Of course, this might not be a convenient way to animate all the time, as you'll have to compensate for the margins etc. – Jave Dec 13 '11 at 13:48