我尝试通过动画更改我的relativeLayout宽度。我的目标是通过动画将WRAP_CONTENT宽度更改为MATCH_PARENT。这是我的源代码
private void setWidthAnimation(View view, int currentHeight, int newHeight) {
ValueAnimator slideAnimator = ValueAnimator
.ofInt(currentHeight, newHeight)
.setDuration(1000);
slideAnimator.addUpdateListener(animation -> {
Integer value = (Integer) animation.getAnimatedValue();
view.getLayoutParams().width = value.intValue();
view.requestLayout();
});
AnimatorSet set = new AnimatorSet();
set.play(slideAnimator);
set.setInterpolator(new BounceInterpolator());
set.start();
view.setBackgroundColor(Color.RED);
}
我这样叫这个方法
if (isKeyBoardOpen)
setWidthAnimation(gifEditableLayout, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
else
setWidthAnimation(gifEditableLayout, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
但是当我运行我的应用程序时,视图的宽度已更改,但没有动画。谁能解释我在做什么错? 谢谢
答案 0 :(得分:1)
您的代码的主要问题是您实际上没有宽度的实际值。
如果您查看自己的setWidthAnimation()
方法,请查看它的显示位置:
ValueAnimator slideAnimator = ValueAnimator
.ofInt(currentHeight, newHeight)
.setDuration(1000);
尤其要查看 currentHeight 和 newHeight 。您知道这两个int变量的值是什么吗?
setWidthAnimation(gifEditableLayout, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
您使用ViewGroup.LayoutParams.WRAP_CONTENT
和ViewGroup.LayoutParams.MATCH_PARENT
作为宽度的值。但是,这些都不是视图的实际宽度。
相反,它们只是LayoutParams
的静态常量:
MATCH_PARENT
是一个静态int常量,值为-1
WRAP_CONTENT
是一个静态int常量,值为-2
因此,您实质上是在告诉ValueAnimator在1秒的时间内从-1到-2或-2到-1的值进行动画处理。
此外,您只是将LayoutParam的宽度设置为-1或-2。幸运的是,这确实实现了View的完成外观,因为View的宽度可以有3种类型的可能性:
layoutParams.width = -1; 这与调用FILL_PARENT
或MATCH_PARENT
layoutParams.width = -2; 这与调用WRAP_CONTENT
layoutParams.width = ANY_OTHER_INT; :这与直接将宽度设置为此值相同。
但是,不会发生动画。
这样做的原因仅仅是因为ValueAnimator实际上不进行任何动画处理。您可以将其更多地视为一个数字计数器。您已对其进行编码,以在1秒的时间内计算从-1到-2的int值。因此,启动时位于WRAP_CONTENT
。下一个可能的int值是-2,它是完成值,因此它将在1秒后精确更新。一秒钟后,它将更新并运行您拥有的代码,该代码将视图的宽度设置为-2。这将立即强制视图为MATCH_PARENT
。
因此,要解决此问题,您需要将实整数值传递给setWidthAnimation()
方法。
答案 1 :(得分:0)
尝试将android:animateLayoutChanges="true"
放在父视图(XML)上。
更多信息:
https://proandroiddev.com/the-little-secret-of-android-animatelayoutchanges-e4caab2fddec
答案 2 :(得分:0)
我真的不知道您的代码是什么,但是我可以建议您我的选择:将您的亲戚放在Constraint内并使用约束集动画。 启动xml
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rootContainer"
tools:context=".MainActivity">
<RelativeLayout
android:id="@+id/rLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</RelativeLayout>
和代码:
RelativeLayout layout;
ConstraintLayout root;
...
layout = findViewById(R.id.rLayout);
root = findViewById(R.id.rootContainer);
public void animate() {
ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(0, 0);
layout.setLayoutParams(params);
ConstraintSet set = new ConstraintSet();
set.clone(root);
set.connect(layout.getId(), ConstraintSet.BOTTOM, root.getId(), ConstraintSet.BOTTOM);
set.connect(layout.getId(), ConstraintSet.TOP, root.getId(), ConstraintSet.TOP);
set.connect(layout.getId(), ConstraintSet.LEFT, root.getId(), ConstraintSet.LEFT);
set.connect(layout.getId(), ConstraintSet.RIGHT, root.getId(), ConstraintSet.RIGHT);
AutoTransition transition = new AutoTransition();
transition.setDuration(1000);
TransitionManager.beginDelayedTransition(root, transition);
set.applyTo(root);
}