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。我在该行的点击侦听器中调用 expandcollapse

截图:

当您的 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();
}