4

It's easy to add layout transitions with this attribute:

android:animateLayoutChanges="true" 

However, the animation you get does not create a pleasing user experience. When elements are added to the layout (I'm using a simple vertical LinearLayout) or change from gone to visible there's a 2-stage process that I think is rather annoying. First, room is prepared for the new element (everything else is pushed down). Then when there's enough room, the new view fades into existence. Likewise, when a view is removed or changes from visible to gone, first it fades out, then the room claimed by it gradually shrinks to zero.

I would really like a way to change the animation to what I really think is the natural way to do it: When adding a view its height gradually changes from zero to its full size, so that first you see just the top, without ever changing the alpha. When removing a view its height gradually changes to its full size to zero, so that near the end of the animation you see just the top, without ever changing the alpha.

How can I accomplish this in Android? (Note: the user can tap on several buttons together and cause several elements to appear / disappear in quick succession, before the animation for the other views ended - or even make something appear while it's still appearing).

Another question that this is perhaps not the place to ask: why isn't this the default?

(And if it's possible, can a slightly different behavior be specified in which first just the bottom of the view appears, rather than the top, like the new view slides down from under the one above it?)

API Why
  • 41
  • 2
  • **"How can I accomplish this in Android?"** The `animateLayoutChanges` attribute only allows boolean values and if "true" will always use a default transition - as for why the default transition "is what it is" then you'd have to ask the Android devs. To do what you want, you'll need to create your own `LayoutTransition` and apply it in code using the corresponding method `setLayoutTransition(...)` https://developer.android.com/reference/android/view/ViewGroup.html#setLayoutTransition(android.animation.LayoutTransition) – Squonk Apr 09 '15 at 22:47
  • 1
    @Squonk thanks, but is there any example of how to accomplish this? Incredibly, a stackoverflow search for layouttransition+setanimator shows just one single result, which I'm looking at right now – API Why Apr 09 '15 at 23:13
  • Sorry, I can't really help further - the only animations I've done are with a `ViewPager` animating `Fragments` in and out (although I suspect the same theory applies). I guess you'd have to inflate your layout (using `setContentView(...)` etc) then use `findViewById(...)` to get the main `ViewGroup` and call `setLayoutTransition(...)` on that. If you go to the main Android developers site and search on animation there are quite a few things to help explain it. – Squonk Apr 09 '15 at 23:28

1 Answers1

2

You have to write your own animator and set it. Code:

 final ViewGroup profileParent = (ViewGroup) view.findViewById(R.id.profileParent);
    LayoutTransition transition = new LayoutTransition();
    Animator appearingAnimation = ObjectAnimator.ofFloat(null, "translationY", 600/*profileParent.getHeight()*/, 0);
    appearingAnimation.addListener(new AnimatorListenerAdapter() {
        public void onAnimationEnd(Animator anim) {
            View view = (View) ((ObjectAnimator) anim).getTarget();
            view.setTranslationY(0f);
        }
    });
    Animator disappearingAnimation = ObjectAnimator.ofFloat(null, "translationY", 0, 600/*profileParent.getHeight()*/);
    appearingAnimation.addListener(new AnimatorListenerAdapter() {
        public void onAnimationEnd(Animator anim) {
            View view = (View) ((ObjectAnimator) anim).getTarget();
            view.setTranslationY(0f);
        }
    });
    transition.setAnimator(LayoutTransition.APPEARING, appearingAnimation);
    transition.setDuration(LayoutTransition.APPEARING, 300);
    transition.setStartDelay(LayoutTransition.APPEARING, 0);

    transition.setAnimator(LayoutTransition.DISAPPEARING, disappearingAnimation);
    transition.setDuration(LayoutTransition.DISAPPEARING, 300);
    transition.setStartDelay(LayoutTransition.DISAPPEARING, 0);

    profileParent.setLayoutTransition(transition);
user39950
  • 464
  • 3
  • 15
  • this does not work in my app. The view I want to remove move out of the screen and left one grey blank, and then the blank disapeared. that is weired – tainy Oct 06 '16 at 13:57