以编程方式调整布局大小(作为动画)

Posted

技术标签:

【中文标题】以编程方式调整布局大小(作为动画)【英文标题】:Resizing layouts programmatically (as animation) 【发布时间】:2011-12-29 17:55:20 【问题描述】:

我想在我的 Activity 中调整一些布局的大小。

这里是主要 XML 的代码:

<LinearLayout
    android:layout_
    android:layout_
    android:layout_weight="1"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/top"
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:background="#3ee3e3" >
    </LinearLayout>

    <LinearLayout
        android:id="@+id/middle"
        android:layout_
        android:layout_
        android:layout_weight="1">
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottom"
        android:layout_
        android:layout_
        android:layout_weight="1"
        android:background="#fe51e6" >
    </LinearLayout>
</LinearLayout>

如您所见,顶部和底部布局高度为 0,而中间 布局涵盖所有地方。

我想以编程方式减小中间布局大小,同时增加顶部 和底部布局大小,直到所有布局具有相同的高度。

我希望它看起来像动画。

我该怎么做?

谢谢

【问题讨论】:

【参考方案1】:

我为了类似的目的写了一个 ResizeAnimation。这很简单,但成本很高。

Java

    /**
     * an animation for resizing the view.
     */
    public class ResizeAnimation extends Animation 
        private View mView;
        private float mToHeight;
        private float mFromHeight;

        private float mToWidth;
        private float mFromWidth;

        public ResizeAnimation(View v, float fromWidth, float fromHeight, float toWidth, float toHeight) 
            mToHeight = toHeight;
            mToWidth = toWidth;
            mFromHeight = fromHeight;
            mFromWidth = fromWidth;
            mView = v;
            setDuration(300);
        

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) 
            float height =
                    (mToHeight - mFromHeight) * interpolatedTime + mFromHeight;
            float width = (mToWidth - mFromWidth) * interpolatedTime + mFromWidth;
            LayoutParams p = mView.getLayoutParams();
            p.height = (int) height;
            p.width = (int) width;
            mView.requestLayout();
        
    

科特林

class ResizeAnimation(
    private val view: View,
    private val toHeight: Float,
    private val fromHeight: Float,
    private val toWidth: Float,
    private val fromWidth: Float,
    duration: Long
) : Animation() 

    init 
        this.duration = duration
    

    override fun applyTransformation(
        interpolatedTime: Float,
        t: Transformation?
    ) 
        val height = (toHeight - fromHeight) * interpolatedTime + fromHeight
        val width = (toWidth - fromWidth) * interpolatedTime + fromWidth
        val layoutParams = view.layoutParams
        layoutParams.height = height.toInt()
        layoutParams.width = width.toInt()
        view.requestLayout()
    

【讨论】:

我猜你也需要覆盖public void initialize & public boolean willChangeBounds @faylon 你为什么说它很昂贵?它会消耗更多内存还是需要更多时间来执行? @NiteshKhatri 耗费了很多cpu,所以动画在低端手机上不会太流畅,尤其是布局本身已经很复杂的时候。我认为我们已经有了更好的方法在新的 android SDK 中实现这样的动画。 @faylon I 支持 2.3 (API 9) 及更高版本。有没有其他更有效的方法来实现这个动画?我会很感激的。 @NiteshKhatri 过去两年我一直没有在 Android 上工作,目前没有时间深入研究这个问题。对此感到抱歉。【参考方案2】:

在 Honeycomb (Android 3.0) 上,AnimatorObjectAnimator 类可实现更流畅的动画效果。

阅读here

有关如何使用反弹插值器为视图组 (LinearLayout) 的移动设置动画的示例。

BounceInterpolator bounceInterpolator = new BounceInterpolator();   
ObjectAnimator anim = ObjectAnimator.ofFloat(myViewGroup, "translationY", 0f, -200 );
anim.setInterpolator(bounceInterpolator);
anim.setDuration(1100).start();

这将触发具有反弹效果的平滑动画,并且真正移动视图,而不像 Honeycomb 之前的动画。来自文档:

之前的动画改变了目标对象的视觉外观……但实际上并没有改变对象本身。

【讨论】:

您能否发布一些代码示例或有关这些对象的更多信息@ddcoy?【参考方案3】:

您还可以使用 Google 的新 Spring 动画调整大小。

SpringAnimation 创建方法:

fun getSpringAnimation(view: View, springAnimationType: FloatPropertyCompat<View>, finalPosition: Float): SpringAnimation 
    val animation = SpringAnimation(view, springAnimationType )
    // create a spring with desired parameters
    val spring = SpringForce()
    spring.finalPosition = finalPosition
    spring.stiffness = SpringForce.STIFFNESS_VERY_LOW // optional
    spring.dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY // optional
    // set your animation's spring
    animation.spring = spring
    return animation

使用情况(调整为原始视图大小的 80%。)

 getSpringAnimation(view, SpringAnimation.SCALE_X, 0.8f).start()
 getSpringAnimation(view, SpringAnimation.SCALE_Y, 0.8f).start()

【讨论】:

以上是关于以编程方式调整布局大小(作为动画)的主要内容,如果未能解决你的问题,请参考以下文章

调整大小后使用自动布局以编程方式居中 UIImageVIew

如何以编程方式设置 UIView 的自动调整大小掩码?

我们可以将具有自动布局的 XIB 加载为以编程方式创建的没有自动布局的视图的子视图,并使用父视图调整子视图的大小吗?

以编程方式调整TextView的大小

Android:如何以编程方式设置布局的大小

当父容器视图约束以编程方式更改时,UINavigationController 子视图不调整大小