Expand and collapse animation

If you search a simple code to expand and collpse a View with an animation you'll find a lot of example. Almost all of the examples extend Animation class.

Instead I would like to use an Animator and its listeners.

Where I come from they say I'm discovering the hot water. I know, but it might be useful to someone.
Here you can see a short video:

The code is very simple:
We'll use two LinearLayout.
   ....
    <!-- Header -->  
    <LinearLayout
        android:id="@+id/header"
        android:layout_width="fill_parent"
        android:layout_height="64dp"
        android:background="#FFF"
        android:orientation="horizontal" >
       
        .....

    </LinearLayout>

    <LinearLayout
        android:id="@+id/expandable"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFF"
        android:orientation="vertical" >

        .....

    </LinearLayout>
In our Activity we simply add a OnClickListener to our Header View.
public class MainActivity extends Activity {

     LinearLayout mLinearLayout;
     LinearLayout mLinearLayoutHeader;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
 
         mLinearLayout = (LinearLayout) findViewById(R.id.expandable);
         //set visibility to GONE
         mLinearLayout.setVisibility(View.GONE);
         mLinearLayoutHeader = (LinearLayout) findViewById(R.id.header);
  
         mLinearLayoutHeader.setOnClickListener(new View.OnClickListener() {
 
             @Override
             public void onClick(View v) {
                 if (mLinearLayout.getVisibility()==View.GONE){
                     expand();
                 }else{
                     collapse();
                 }
             }
         });
}
Now we'll create a ValueAnimator to animate the Layout height from 0 to original height to expand the view and from original height to 0 to collpse the view.
private void expand() {
     //set Visible
     mLinearLayout.setVisibility(View.VISIBLE);
     
     final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
     final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
     mLinearLayout.measure(widthSpec, heightSpec);
     
     ValueAnimator mAnimator = slideAnimator(0, mLinearLayout.getMeasuredHeight());
     mAnimator.start();
}
 
private void collapse() {
     int finalHeight = mLinearLayout.getHeight();

     ValueAnimator mAnimator = slideAnimator(finalHeight, 0);
}

private ValueAnimator slideAnimator(int start, int end) {
  
     ValueAnimator animator = ValueAnimator.ofInt(start, end);
}
The previous code snippets, has no real effect. We need to implement the Animation Listeners.
With a AnimatorUpdateListener we'll modify the height.
private ValueAnimator slideAnimator(int start, int end) {
  
    ValueAnimator animator = ValueAnimator.ofInt(start, end);
  
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
         @Override
         public void onAnimationUpdate(ValueAnimator valueAnimator) {
            //Update Height
            int value = (Integer) valueAnimator.getAnimatedValue();
            ViewGroup.LayoutParams layoutParams = mLinearLayout.getLayoutParams();
            layoutParams.height = value;
            mLinearLayout.setLayoutParams(layoutParams);
         }
    });
    return animator;
}
With this code we obtain our purpose.
The final step is to set the visibility to View.GONE when we collapse the view.
We'll use an AnimatorListener.
private void collapse() {
     int finalHeight = mLinearLayout.getHeight();

     ValueAnimator mAnimator = slideAnimator(finalHeight, 0);
  
     mAnimator.addListener(new Animator.AnimatorListener() {
          @Override
          public void onAnimationEnd(Animator animator) {
             //Height=0, but it set visibility to GONE
              mLinearLayout.setVisibility(View.GONE);
          }
          .....   
     });
     mAnimator.start();
}

You can get code from GitHub:

Comments

  1. How to fix if mLinearLayout.getMeasuredHeight () returns a fixed size all the time, although the form itself changes?

    ReplyDelete
  2. Thanks for writing such an interesting post on your blog. I enjoyed reading it very much. This kind of information was previously unavailable. I appreciate you writing this profile today. You can find the scrolling speed optimizer here, if you're a speedy gamer. You can also find a Mouse Button & Scroll Wheel TestTool here.

    ReplyDelete

Post a Comment

Popular posts from this blog

AntiPattern: freezing a UI with Broadcast Receiver

NotificationListenerService and kitkat

How to centralize the support libraries dependencies in gradle