动画实现两种方式:
ObjectAnimator animator1 = ObjectAnimator.ofFloat(tvContent1, View.TRANSLATION_Y, hFrom, hTo);
ObjectAnimator animator1 = ObjectAnimator.ofInt(wrapper, “height”, hFrom, hTo);
但是效果完全不同:
如下图:
public class SecondActivity extends AppCompatActivity {
private TextView tvTitle1, tvTitle2;
private TextView tvContent1, tvContent2;
private ViewWrapper wrapper;
private int height1, height2;
private boolean isAnimating1, isAnimating2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
tvTitle1 = (TextView) findViewById(R.id.tv_title);
tvContent1 = (TextView) findViewById(R.id.tv_content);
tvTitle2 = (TextView) findViewById(R.id.tv_title2);
tvContent2 = (TextView) findViewById(R.id.tv_content2);
wrapper = new ViewWrapper(tvContent2);
initHeight();
tvTitle1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startAnimator1();
}
});
tvTitle2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startAnimator2();
}
});
}
private void initHeight() {
tvContent1.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
height1 = tvContent1.getHeight();
tvContent1.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
tvContent2.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
height2 = tvContent2.getHeight();
tvContent2.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
private void startAnimator1() {
if (isAnimating1) return;
final boolean isExpand = (View.VISIBLE == tvContent1.getVisibility());
int hFrom = 0, hTo = 0;
if (!isExpand) {//已显示,需要隐藏
hFrom = -height1;
} else {//已隐藏 需要显示
hTo = -height1;
}
ObjectAnimator animator1 = ObjectAnimator.ofFloat(tvContent1, View.TRANSLATION_Y, hFrom, hTo);
animator1.setDuration(600);
animator1.setInterpolator(new AccelerateDecelerateInterpolator());
tvContent1.setVisibility(View.VISIBLE);
animator1.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
isAnimating1 = true;
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
isAnimating1 = false;
tvContent1.setVisibility(isExpand ? View.GONE : View.VISIBLE);
}
});
animator1.start();
}
private void startAnimator2() {
if (isAnimating2) return;
final boolean isExpand = (View.VISIBLE == tvContent2.getVisibility());
int hFrom = 0, hTo = 0;
if (isExpand) {//已显示,需要隐藏
hFrom = height2;
} else {//已隐藏 需要显示
hTo = height2;
}
ObjectAnimator animator2 = ObjectAnimator.ofInt(wrapper, "height", hFrom, hTo);
animator2.setDuration(600);
animator2.setInterpolator(new AccelerateDecelerateInterpolator());
tvContent2.setVisibility(View.VISIBLE);
animator2.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
isAnimating2 = true;
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
isAnimating2 = false;
tvContent2.setVisibility(isExpand ? View.GONE : View.VISIBLE);
}
});
animator2.start();
}
}
其中 高度ofInt时 用到属性动画 包装类:
/**
* 属性动画view包装类
*/
public class ViewWrapper implements Serializable {
private View mTarget;
public ViewWrapper(View target) {
mTarget = target;
}
public int getWidth() {
return mTarget.getLayoutParams().width;
}
public void setWidth(int width) {
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
}
public int getHeight() {
return mTarget.getLayoutParams().height;
}
public void setHeight(int height) {
mTarget.getLayoutParams().height = height;
mTarget.requestLayout();
}
}