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

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

这里是主要 XML 的代码:

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/top"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:background="#3ee3e3" >
    </LinearLayout>

    <LinearLayout
        android:id="@+id/middle"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1">
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottom"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:background="#fe51e6" >
    </LinearLayout>
</LinearLayout>

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

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

我希望它看起来像动画。

我该怎么做?

谢谢

【问题讨论】:

    标签: android layout animation android-animation


    【解决方案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()
    

    【讨论】:

      猜你喜欢
      • 2012-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-03
      • 1970-01-01
      • 2015-05-02
      • 1970-01-01
      • 2018-02-04
      相关资源
      最近更新 更多