以编程方式调整布局大小(作为动画)
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) 上,Animator
和 ObjectAnimator
类可实现更流畅的动画效果。
阅读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