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

前端之家收集整理的这篇文章主要介绍了android – 展开/折叠动画:小滞后|| MeasureSpec返回错误的值前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我使用以下两种方法( inspired/copied from here)通过点击“标题”-TextView来展开和折叠ScrollView中的一些TextView.

伪布局结构:

<ScrollView>
    <LinearLayout>
        <LinearLayout>
            <!-- some other stuff here -->
        </LinearLayout>
        <TextView "header1"/>
        <View "fancydivider"/>
        <TextView "content1">
        <TextView "header2"/>
        <View "fancydivider"/>
        <TextView "content2">
    </LinearLayout>
</ScrollView>

Divider是一个简单的View,heightset为1dp. content-TextViews的内容包括

<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;
}

问题在这里:一切正常 – 直到展开动画到达文本的最后一行 – 如果它的字符太少,那么它滞后,跳跃,爆炸? – 但是您要调用它 – 直到完全展开.

崩溃似乎工作正常.

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

一些测试:

> 4行,第四行全部17个以上的字符工作正常,少于18个字符,并且滞后.
> 3行和不相关的字数在最后一行工作正常.
>有时动画首先展开,但不是第二次.
>看来,TextView的计算错误.有一个高乘数,我看到一些文本翻转起来,在下一个标题TextView中0.5s
>在expand中删除smoothScrollTo不会改变任何东西(除了滚动当然..)
>其他内插器也有“打嗝”,但更短

重要:

>一些登录applyTransformation(见下文)让我指出,我看到最后的高度打印了两次 – 只有50点(像素?dp?)的差异. //顺利增加高度然后:
最终高度= 202高度= 252最终高度= 252当我得到targetHeight = 203 – 所以高度先计算错误,但是然后一些魔法发生?

@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());
    }
}

有人可以指出我失踪了吗?

解决方法

这可能是因为扩展最后一个元素可能会触发滚动,因为布局的高度越来越大,因此将显示“推”

尝试在底部添加一个FrameLayout,高度为20dp,如果有任何差异,请尝试观察

猜你在找的Android相关文章