【Android】动画 —— view高度渐变的动画

【关键词】 Android 高度 动画
【问题】

  • 实现可见度为 gone 的 view ,高度从0变化到测量的高度;
  • 如果view 可见度为 gone, 直接通过 view.getHeight(); 得到的是0;
  • 虽然可以通过一个固定值来设置高度,但是如果高度设置的不准就会存在适配问题(应该有一种方法在gone的情况下也可以获取到view的高度);
【效果图】 【分析】
  • 找到一种方式可以在 可见度为 GONE 的情况下,也能获取到准确的高度的方法,具体信息参见最后【参考资料】;
【解决方案】
  • 如果是显示:在动画执行之前,设置可见性为 Visible; 获取到要显示到的最大高度,让其高度通过动画的方式逐渐变大;
  • 如果是隐藏:通过 view.getLayoutParam.height 获取到当前显示时的高度,让其逐渐变化到0;动画执行后设置可见性为GONE;
【代码】 【【Android】动画 —— view高度渐变的动画】 使用方法:

// 显示 View vHead = findViewById(R.id.llyt_v_head); AnimatorUtil.animHeightToView(this, vHead, true, 200); // 隐藏 View vHead = findViewById(R.id.llyt_v_head); AnimatorUtil.animHeightToView(this, vHead, false, 200); 帮助类

public class AnimatorUtil { // 高度渐变的动画; public static void animHeightToView(final View v, final int start, final int end, final boolean isToShow, long duration) { ValueAnimator va = ValueAnimator.ofInt(start, end); final ViewGroup.LayoutParams layoutParams = v.getLayoutParams(); va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { int h = (int) animation.getAnimatedValue(); layoutParams.height = h; v.setLayoutParams(layoutParams); v.requestLayout(); } }); va.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { if (isToShow) { v.setVisibility(View.VISIBLE); } super.onAnimationStart(animation); } @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); if (!isToShow) { v.setVisibility(View.GONE); } } }); va.setDuration(duration); va.start(); } public static void animHeightToView(final Activity context, final View v, final boolean isToShow, final long duration) { if (isToShow) { // 显示:通过上下文对象context获取可见度属性为 gone 的 view 的高度; Display display = context.getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); v.measure(size.x, size.y); int end= v.getMeasuredHeight(); animHeightToView(v, 0, end, isToShow, duration); } else { // 隐藏:从当前高度变化到0,最后设置不可见; animHeightToView(v, v.getLayoutParams().height, 0, isToShow, duration); } } 【扩展】

// WindowManager也可以直接通过Context获取; WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); 【参考资料】
  • Android - 在View显示前获取其高度和宽度

    Android开发经常需要在Activity显示前获取某个View的高度和宽度,例如:程序需要在onCreate()方法中得到一个View的高度和宽度,或者需要知道一个Visibility为Gone的View的高度和宽度。此时如果直接调用View的getWidth()和getHeight()方法,得到的结果是0。 原因是在上述情况中,View并没有实际绘制,既然原因找到了,解决办法也就有了,我们可以调用View.measure()方法,之后在获取View.getMeasuredWidth()和View.getMeasuredHeight()。 Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); view.measure(size.x, size.y); int width = view.getMeasuredWidth(); int height = view.getMeasuredHeight();

    推荐阅读