为recyclerview和textview翻译动画并不顺利

时间:2016-03-21 15:49:16

标签: android animation android-recyclerview translate-animation

我想在TextView下方显示一个Toolbar,如果有新事件进入,则应该显示。它应该从Toolbar下方向下滑动,显示为1 -2秒然后再次向上滑动。 TextView下面是一个RecyclerView,在GridLayout中订购了多个项目。

layout with textview and recyclerview

为实现这一目标,我正在使用TranslateAnimation让动画再次向上滑动:

TranslateAnimation animate = new TranslateAnimation(0, 0, 0, -tvStatus.getHeight());
animate.setDuration(1000);
animate.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {
    }
    @Override
    public void onAnimationEnd(Animation animation) {
        tvStatus.setVisibility(View.GONE);
    }
    @Override
    public void onAnimationRepeat(Animation animation) {
    }
});
tvStatus.startAnimation(animate);

TextView本身的滑动动画效果很好,但RecyclerView动画效果不佳。 TextView再次向上滑动,直到它被隐藏,并且短时间内存在间隙。 gap after textview disappears

然后ReclerView只是跳起来,这看起来不太好。

我的问题是:RecylerView开始向上滑动时,如何调整代码以使TextView向上滑动?

编辑 - 解决方案:

我调整了我的解决方案,包括来自Francescs answer的输入。我只是通过改变视图的高度来解决没有翻译的动画。

展开状态栏的方法:

public void expand() {
                    //set Visible
                    tvStatus.setVisibility(View.VISIBLE);
                    mAnimator = slideAnimator(0, mHeight);
                    mAnimator.setDuration(600);
                    mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
                    mAnimator.start();
}

折叠状态栏的方法:

private void collapse() {


        int finalHeight = tvStatus.getHeight();
                    ValueAnimator mAnimator = slideAnimator(finalHeight, 0);
                    mAnimator.setDuration(500);
                    mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
                    mAnimator.addListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            tvStatus.setVisibility(View.GONE);
                        }
                    });
                    mAnimator.start();
}

价值动画师

private ValueAnimator slideAnimator(int start, int end) {

        ValueAnimator animator = ValueAnimator.ofInt(start, end);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                //Update Height
                int value = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = tvStatus.getLayoutParams();
                layoutParams.height = value;
                tvStatus.setLayoutParams(layoutParams);
            }
        });
        return animator;
}
在onCreate中调用

measureTextHeight()方法以获取TextView高度:

public void measureTextHeight() {
        tvStatus.setVisibility(View.VISIBLE);
        tvStatus.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                mHeight = tvStatus.getHeight();
                if (mHeight > 0) {
                    tvStatus.getViewTreeObserver().removeOnPreDrawListener(this);
                    tvStatus.setVisibility(View.GONE);
                    return false;
                }
                return true;
            }
        });
    }

1 个答案:

答案 0 :(得分:1)

您还需要为TextView的布局参数设置动画,而不仅仅是翻译。添加此项并与您的翻译动画并行运行。在开始动画之前确保知道文本视图高度(如果textview不可见,则可能需要使用预绘制侦听器):

final ViewGroup.LayoutParams layoutParams = mTextView.getLayoutParams();
mTextView.setVisibility(View.VISIBLE);
ValueAnimator anim = ValueAnimator.ofInt(mTextView.getHeight());
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        int val = (Integer) valueAnimator.getAnimatedValue();
        layoutParams.height = val;
        mTextView.setLayoutParams(layoutParams);
    }
});
anim.setDuration(1000);
anim.start(); 

编辑:

测量文本视图的高度,使其在您的布局中可见,然后添加一个onPreDrawListener来扩展您的布局:

private void measureTextHeight() {
    mTextView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            mTextViewHeight = mTextView.getHeight();
            if (mTextViewHeight > 0) {
                mTextView.getViewTreeObserver().removeOnPreDrawListener(this);
                mTextView.setTranslationY(-mTextViewHeight);
                mTextView.setVisibility(View.GONE);
                return false;
            }
            return true;
        }
    });
}

现在您拥有文本视图的高度,因此您可以使用上面的函数显示它。要隐藏它,请执行以下操作:

final ViewGroup.LayoutParams layoutParams = mTextView.getLayoutParams();
mTextView.setVisibility(View.VISIBLE);
ValueAnimator anim = ValueAnimator.ofInt(mTextView.getHeight());
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        int val = (Integer) valueAnimator.getAnimatedValue();
        layoutParams.height = mTextViewHeight - val;
        mTextView.setLayoutParams(layoutParams);
    }
});
anim.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationCancel(Animator animation) {
        mTextView.setVisibility(View.GONE);
    }

    @Override
    public void onAnimationEnd(Animator animation) {
        mTextView.setVisibility(View.GONE);
    }
});
anim.setDuration(1000);
anim.start();

请记住,这需要与您的翻译动画并行运行,因此您可以使用动画集来同时运行它们。