Created
April 6, 2013 17:14
-
-
Save venator85/5326846 to your computer and use it in GitHub Desktop.
A LinearLayout subclass that can be collapsed and expanded in an animated fashion. Relies on NineOldAndroids for animation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.animatedpiechart; | |
import android.content.Context; | |
import android.util.AttributeSet; | |
import android.view.MotionEvent; | |
import android.view.ViewGroup; | |
import android.view.animation.AccelerateDecelerateInterpolator; | |
import android.view.animation.Interpolator; | |
import android.widget.LinearLayout; | |
import com.nineoldandroids.animation.Animator; | |
import com.nineoldandroids.animation.AnimatorListenerAdapter; | |
import com.nineoldandroids.animation.IntEvaluator; | |
import com.nineoldandroids.animation.ValueAnimator; | |
public class CollapsableLinearLayout extends LinearLayout { | |
private class HeightEvaluator extends IntEvaluator { | |
@Override | |
public Integer evaluate(float fraction, Integer startValue, Integer endValue) { | |
int height = super.evaluate(fraction, startValue, endValue); | |
ViewGroup.LayoutParams params = getLayoutParams(); | |
params.height = height; | |
setLayoutParams(params); | |
return height; | |
} | |
} | |
private ValueAnimator animator; | |
private Interpolator interpolator = new AccelerateDecelerateInterpolator(); | |
private boolean animating; | |
private int expandedHeight; | |
private long duration = 600; | |
public CollapsableLinearLayout(Context context) { | |
super(context); | |
onInit(); | |
} | |
public CollapsableLinearLayout(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
onInit(); | |
} | |
public CollapsableLinearLayout(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
onInit(); | |
} | |
protected void onInit() { | |
} | |
@Override | |
public boolean onInterceptTouchEvent(MotionEvent ev) { | |
// consume all touch events when animating | |
if (animating) { | |
return true; | |
} | |
return super.onInterceptTouchEvent(ev); | |
} | |
@Override | |
protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
super.onSizeChanged(w, h, oldw, oldh); | |
if ((w != oldw || h != oldh) && !animating && h != 0) { | |
expandedHeight = h; | |
} | |
} | |
public void setAnimationDuration(long duration) { | |
this.duration = duration; | |
} | |
public long getAnimationDuration() { | |
return duration; | |
} | |
public void setInterpolator(Interpolator interpolator) { | |
this.interpolator = interpolator; | |
} | |
public Interpolator getInterpolator() { | |
return interpolator; | |
} | |
public void expand() { | |
if (getHeight() != expandedHeight) { | |
animateHeight(0, expandedHeight); | |
} | |
} | |
public void collapse() { | |
if (getHeight() != 0) { | |
animateHeight(expandedHeight, 0); | |
} | |
} | |
private void animateHeight(int startHeight, int endHeight) { | |
long previousAnimationPlayTime = -1; | |
if (animator != null && animator.isRunning()) { | |
previousAnimationPlayTime = animator.getCurrentPlayTime(); | |
animator.cancel(); | |
} | |
animator = ValueAnimator.ofObject(new HeightEvaluator(), startHeight, endHeight); | |
animator.setInterpolator(interpolator); | |
animator.setDuration(duration); | |
animator.addListener(new AnimatorListenerAdapter() { | |
@Override | |
public void onAnimationStart(Animator animation) { | |
animating = true; | |
} | |
@Override | |
public void onAnimationEnd(Animator animation) { | |
animating = false; | |
} | |
}); | |
animator.start(); | |
if (previousAnimationPlayTime != -1) { | |
animator.setCurrentPlayTime(duration - previousAnimationPlayTime); | |
} | |
} | |
@Override | |
protected void onLayout(boolean changed, int l, int t, int r, int b) { | |
// We don't want children to move during animation. | |
// Also, don't layout children if our height is zero. | |
if (!animating && t != b) { | |
super.onLayout(changed, l, t, r, b); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment