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