TextView动画只展开一行
TextView animation expand only one line
我需要在单击按钮时为 TextView 设置动画。 TextView 的高度是wrap_content。此 TextView 位于 RecyclerView 行内,我需要将其从可见性扩展到包含内容的真实高度。我使用了 ValueAnimator。
private ValueAnimator slideAnimator(int start, int end) {
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = tvAdditional.getLayoutParams();
layoutParams.height = value;
tvAdditional.setLayoutParams(layoutParams);
}
});
return animator;
}
private void expand(View v) {
v.setVisibility(View.VISIBLE);
v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ValueAnimator mAnimator = slideAnimator(0, v.getMeasuredHeight());
mAnimator.start();
}
private void collapse(final View v) {
int finalHeight = v.getHeight();
ValueAnimator mAnimator = slideAnimator(finalHeight, 0);
mAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animator) {
v.setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
mAnimator.start();
}
在调试中,我注意到当我在 expand
中的视图上使用 getMeasuredHeight()
方法时,该值始终为 76,即使我添加了不止一行的项目也是如此。
P.s。我在该行的点击侦听器中调用 expand
和 collapse
。
截图:
当您的 Visibility 为 GONE 时,在实际绘制之前您无法知道它的测量高度。为此,您需要在该 TextView 上安装 GlobalLayoutListener,这样您就可以在绘制时获得它的测量高度。
在你的expand方法中,我看到你把Visibility设置为Visible,然后尝试测量它,不会立即绘制,所以你无法获得高度。
那么,如果 TextView 的可见性最初消失了,您可以做些什么来获取 TextView 的实际高度,首先您应该将初始可见性更改为 VISIBLE,其次,设置全局布局侦听器,第三步,存储 TextView 的测量后的全局值中的高度,作为最后一步,您可以将 TextView 的 Visibility 设置为 GONE。
此过程通常非常快,因此您无法用肉眼看到 TextView 的可见性从 VISIBLE 变为 GONE。
已解决
我更改了我的 expand
方法,添加了一个侦听器,在该侦听器中我在动画结束时将高度设置为 wrap_content:
private void expand(final View v) {
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
final int targetHeight = v.getMeasuredHeight();
ValueAnimator mAnimator = slideAnimator(0, targetHeight);
mAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
v.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
v.requestLayout();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
mAnimator.start();
}
我需要在单击按钮时为 TextView 设置动画。 TextView 的高度是wrap_content。此 TextView 位于 RecyclerView 行内,我需要将其从可见性扩展到包含内容的真实高度。我使用了 ValueAnimator。
private ValueAnimator slideAnimator(int start, int end) {
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = tvAdditional.getLayoutParams();
layoutParams.height = value;
tvAdditional.setLayoutParams(layoutParams);
}
});
return animator;
}
private void expand(View v) {
v.setVisibility(View.VISIBLE);
v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ValueAnimator mAnimator = slideAnimator(0, v.getMeasuredHeight());
mAnimator.start();
}
private void collapse(final View v) {
int finalHeight = v.getHeight();
ValueAnimator mAnimator = slideAnimator(finalHeight, 0);
mAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animator) {
v.setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
mAnimator.start();
}
在调试中,我注意到当我在 expand
中的视图上使用 getMeasuredHeight()
方法时,该值始终为 76,即使我添加了不止一行的项目也是如此。
P.s。我在该行的点击侦听器中调用 expand
和 collapse
。
截图:
当您的 Visibility 为 GONE 时,在实际绘制之前您无法知道它的测量高度。为此,您需要在该 TextView 上安装 GlobalLayoutListener,这样您就可以在绘制时获得它的测量高度。
在你的expand方法中,我看到你把Visibility设置为Visible,然后尝试测量它,不会立即绘制,所以你无法获得高度。
那么,如果 TextView 的可见性最初消失了,您可以做些什么来获取 TextView 的实际高度,首先您应该将初始可见性更改为 VISIBLE,其次,设置全局布局侦听器,第三步,存储 TextView 的测量后的全局值中的高度,作为最后一步,您可以将 TextView 的 Visibility 设置为 GONE。
此过程通常非常快,因此您无法用肉眼看到 TextView 的可见性从 VISIBLE 变为 GONE。
已解决
我更改了我的 expand
方法,添加了一个侦听器,在该侦听器中我在动画结束时将高度设置为 wrap_content:
private void expand(final View v) {
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
final int targetHeight = v.getMeasuredHeight();
ValueAnimator mAnimator = slideAnimator(0, targetHeight);
mAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
v.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
v.requestLayout();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
mAnimator.start();
}