展开/折叠动画:小滞后|| MeasureSpec返回错误的值

时间:2015-12-08 10:57:32

标签: android android-animation

我在expand中使用以下两种方法(inspired/copied from herecollapseTextViews ScrollView点击“标题” - { {1}}。

伪布局结构:

TextView

分隔符是一个简单的<ScrollView> <LinearLayout> <LinearLayout> <!-- some other stuff here --> </LinearLayout> <TextView "header1"/> <View "fancydivider"/> <TextView "content1"> <TextView "header2"/> <View "fancydivider"/> <TextView "content2"> </LinearLayout> </ScrollView> View设置为height。内容 - 1dp样式包括:

TextViews

和一些边际&amp;填充。

这里的方法:

    <item name="android:layout_height">0dp</item>
    <item name="android:layout_width">match_parent</item>

问题在这里:一切正常 - 直到public static void expand(final View v) { //v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); int matchParentMeasureSpec = View.MeasureSpec.makeMeasureSpec(((View) v.getParent()).getWidth(), View.MeasureSpec.EXACTLY); int wrapContentMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); v.measure(matchParentMeasureSpec, wrapContentMeasureSpec); final int targetHeight = v.getMeasuredHeight(); // Older versions of android (pre API 21) cancel animations for views with a height of 0. v.getLayoutParams().height = 1; v.setVisibility(View.VISIBLE); Animation a = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { v.getLayoutParams().height = interpolatedTime == 1 ? ViewGroup.LayoutParams.WRAP_CONTENT : (int) (targetHeight * interpolatedTime); scrollView.smoothScrollTo(0, (int) (targetHeight * interpolatedTime)); v.requestLayout(); } @Override public boolean willChangeBounds() { return true; } }; a.setInterpolator(easeInOutQuart); a.setDuration(computeDurationFromHeight(v)); v.startAnimation(a); } public static void collapse(final View v) { final int initialHeight = v.getMeasuredHeight(); Animation a = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { if (interpolatedTime == 1) { v.setVisibility(View.GONE); } else { v.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime); v.requestLayout(); } } @Override public boolean willChangeBounds() { return true; } }; a.setInterpolator(easeInOutQuart); a.setDuration(computeDurationFromHeight(v)); v.startAnimation(a); } private static int computeDurationFromHeight(View view) { // 1dp/ms * multiplier return (int) (view.getMeasuredHeight() / view.getContext().getResources().getDisplayMetrics().density) * 4; } 到达文本的最后一行 - 如果expand animation上的characters太少,那么滞后,跳跃,爆炸? - 但是你要打电话 - 直到完全展开。

Collapsing似乎工作正常。

我尝试了其他Interpolator值,方法computeDurationFromHeight中的另一个乘数。

一些测试:

    • 4行,在第四行,超过17个字符的工作正常,少于18个字符且滞后。

    • 最后一行的3行和无关数量的字符工作正常。

    • 有时animation适用于第一个expand,但不适用于第二个。

    • 似乎TextView计算错误。我看到multiplier有一些text高的TextView。在下一个标题smoothScrollTo
    • 上方0.5秒
    • 删除expand中的applyTransformation不会改变任何内容(当然滚动除外)。
    • 其他插补器也有'打嗝',但更短

    重要:

  • 一些登录final height(见下文)让我明白了,我发现//smoothly increasing height and then:打印两次 - 恰好有50个点(像素?dp? ) 区别。 final height = 202 height = 252 final height = 252 targetHeight = 203虽然我得到height - 所以@Override protected void applyTransformation(float interpolatedTime, Transformation t) { v.getLayoutParams().height = interpolatedTime == 1 ? ViewGroup.LayoutParams.WRAP_CONTENT : (int) (targetHeight * interpolatedTime); v.requestLayout(); scrollView.smoothScrollTo(0, interpolatedTime == 1 ? v.getHeight() : (int) (targetHeight * interpolatedTime)); Log.d("Anim", "height = " + v.getHeight()); if (interpolatedTime == 1){ Log.d("Anim", "final height = " + v.getHeight()); } } 首先计算错误,但之后会发生一些魔法?
NetworkManager

有人能说出我错过的东西吗?

2 个答案:

答案 0 :(得分:0)

它可能会导致因为花费最后一个元素可能会触发滚动因为布局的高度变大,因此“推”显示器

尝试在底部添加一个高度为20dp的FrameLayout,并尝试观察它是否有任何区别

答案 1 :(得分:0)

我99%确定您需要将<item name="android:layout_height">0dp</item>(被动画的TextView更改为wrap_content,并将其初始状态设置为{ {1}}(因为这是崩溃动画后的最终状态)。