Android - 使用 align-parent (Kotlin) 动画布局
Android - Animating layout using align-parent (Kotlin)
当用户点击布局中的 EditText 时,我需要从屏幕底部到顶部设置布局动画。这是我执行此操作的代码:
myEditText.setOnFocusChangeListener() { _, focused ->
if (focused) {
val animation = object: Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
val params = myLayout.getLayoutParams() as RelativeLayout.LayoutParams
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE)
myLayout.setLayoutParams(params)
}
}
animation.duration = 1000
myEditText.startAnimation(animation)
}
}
当我点击 EditText 时,"myLayout" 正确地转到屏幕顶部。但是,有两个问题:
1)没有动画,就是跳到最上面。我希望它 "slide" 达到顶部。
2) 更重要的是,设置为 "below" 且相对于 myLayout 的视图不会随之上升。我知道这些设置正确,因为当我在 XML 中添加顶部对齐方式时,它们会随之而来。但从程序上看,它们似乎停留在屏幕下方,仍然隐藏着。
我尝试了另一种使用 ObjectAnimator 的方法,手动向上移动所有视图:
val anims = AnimatorSet();
val anim1 = ObjectAnimator.ofFloat(myLayout, View.TRANSLATION_Y, -1000f)
val anim2 = ObjectAnimator.ofFloat(layoutBelow, View.TRANSLATION_Y, -1000f)
val anim3 = ObjectAnimator.ofFloat(layoutBelowBelow, View.TRANSLATION_Y, -1000f)
anims.playTogether(anim1, anim2, anim3)
anims.start()
这样做可以使动画正常工作,但 "myLayout" 下面的视图仍然不可见!我很好奇它们最初不在屏幕上是否有所不同 (?)
关于我可能遗漏了什么的想法?如果有更好的方法来处理这个问题,我也愿意接受不同的方法。
这种动画可以通过 Transition API
完成,现在在 androix
包中可用。
这里是 Button
是 RelativeLayout
中的 centerVertical
的例子。 TextView
对齐低于 Button
。单击按钮后,我删除 centerVertical
规则并将 alignParentTop
规则添加到 Button
。几乎1行就可以完成所有的动画。
import androidx.transition.AutoTransition;
import androidx.transition.TransitionManager;
....
@Override
protected void onCreate(Bundle savedInstanceState) {
....
View button = findViewById(R.id.button);
button.setOnClickListener(btn -> {
animate(btn);
});
}
private void animate(View button) {
RelativeLayout parent = findViewById(R.id.relativeLayout);
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) button.getLayoutParams();
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
lp.removeRule(RelativeLayout.CENTER_VERTICAL);
AutoTransition transition = new AutoTransition();
transition.setDuration(2000);
TransitionManager.beginDelayedTransition(parent, transition);
button.setLayoutParams(lp);
}
布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Button" />
<TextView
android:id="@+id/bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/button"
android:layout_centerHorizontal="true"
android:text="bottom text" />
</RelativeLayout>
结果:
当用户点击布局中的 EditText 时,我需要从屏幕底部到顶部设置布局动画。这是我执行此操作的代码:
myEditText.setOnFocusChangeListener() { _, focused ->
if (focused) {
val animation = object: Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
val params = myLayout.getLayoutParams() as RelativeLayout.LayoutParams
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE)
myLayout.setLayoutParams(params)
}
}
animation.duration = 1000
myEditText.startAnimation(animation)
}
}
当我点击 EditText 时,"myLayout" 正确地转到屏幕顶部。但是,有两个问题:
1)没有动画,就是跳到最上面。我希望它 "slide" 达到顶部。
2) 更重要的是,设置为 "below" 且相对于 myLayout 的视图不会随之上升。我知道这些设置正确,因为当我在 XML 中添加顶部对齐方式时,它们会随之而来。但从程序上看,它们似乎停留在屏幕下方,仍然隐藏着。
我尝试了另一种使用 ObjectAnimator 的方法,手动向上移动所有视图:
val anims = AnimatorSet();
val anim1 = ObjectAnimator.ofFloat(myLayout, View.TRANSLATION_Y, -1000f)
val anim2 = ObjectAnimator.ofFloat(layoutBelow, View.TRANSLATION_Y, -1000f)
val anim3 = ObjectAnimator.ofFloat(layoutBelowBelow, View.TRANSLATION_Y, -1000f)
anims.playTogether(anim1, anim2, anim3)
anims.start()
这样做可以使动画正常工作,但 "myLayout" 下面的视图仍然不可见!我很好奇它们最初不在屏幕上是否有所不同 (?)
关于我可能遗漏了什么的想法?如果有更好的方法来处理这个问题,我也愿意接受不同的方法。
这种动画可以通过 Transition API
完成,现在在 androix
包中可用。
这里是 Button
是 RelativeLayout
中的 centerVertical
的例子。 TextView
对齐低于 Button
。单击按钮后,我删除 centerVertical
规则并将 alignParentTop
规则添加到 Button
。几乎1行就可以完成所有的动画。
import androidx.transition.AutoTransition;
import androidx.transition.TransitionManager;
....
@Override
protected void onCreate(Bundle savedInstanceState) {
....
View button = findViewById(R.id.button);
button.setOnClickListener(btn -> {
animate(btn);
});
}
private void animate(View button) {
RelativeLayout parent = findViewById(R.id.relativeLayout);
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) button.getLayoutParams();
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
lp.removeRule(RelativeLayout.CENTER_VERTICAL);
AutoTransition transition = new AutoTransition();
transition.setDuration(2000);
TransitionManager.beginDelayedTransition(parent, transition);
button.setLayoutParams(lp);
}
布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Button" />
<TextView
android:id="@+id/bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/button"
android:layout_centerHorizontal="true"
android:text="bottom text" />
</RelativeLayout>
结果: