Android:Comp之后会重置动画位置
我正在使用xml定义的动画将视图滑出屏幕。 问题是,动画完成后,它将立即重置为其原始位置。 我需要知道如何解决这个问题。 这是xml:
这是我用来调用它的Java:
homeScrn = (View)findViewById(R.id.homescreen);
slideLeftOut = AnimationUtils.loadAnimation(this, R.anim.slide_left_out);
//Set Click Listeners For Menu
btnHelp.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
LayoutInflater.from(getApplicationContext()).inflate(R.layout.help, (ViewGroup)findViewById(R.id.subpage), true);
homeScrn.startAnimation(slideLeftOut);
}
});
因此,基本上发生的是我在一个视图下面放大一个视图。 然后为左上方的顶部动画。 一旦离开屏幕且动画完成,它将重新设置其位置。
LoneWolfPR asked 2019-10-13T23:07:14Z
8个解决方案
102 votes
终于找到了解决方法,正确的方法是layout(),
如果要在xml中定义动画,则应执行以下操作
android:interpolator="@android:anim/decelerate_interpolator"
android:fillAfter="true">
android:fromXDelta="0%"
android:toXDelta="-100%"
android:duration="1000"/>
您会看到我已经在25680946268843550550标记中定义了layout(),如果尝试在LayoutParams标记中定义它将无法工作,可能是框架中的错误!
然后在代码中
Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_out);
someView.startAnimation(anim);
要么
TranslateAnimation animation = new TranslateAnimation(-90, 150, 0, 0);
animation.setFillAfter(true);
animation.setDuration(1800);
someView.startAnimation(animation);
那么它肯定会工作!
现在这有点棘手,似乎视图实际上已移动到新位置,但实际上视图的像素已移动,即视图实际上处于其初始位置但不可见,如果有一些按钮,则可以对其进行测试 或视图中的可点击视图(在我的情况下为布局),以解决必须手动将视图/布局移动到新位置的问题
public TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
new TranslateAnimation(-90, 150, 0, 0);
现在我们可以看到我们的动画将从-90 x轴开始到150 x轴
所以我们要做的就是
someView.setAnimationListener(this);
和在
public void onAnimationEnd(Animation animation)
{
someView.layout(150, 0, someView.getWidth() + 150, someView.getHeight());
}
现在让我解释layout()
它将布局移到新位置,第一个参数定义左边,我们为150,因为平移动画将视图的动画设置为150 x轴,顶部为0,因为我们没有设置y轴的动画,在右边我们已经完成了 layout()基本上,我们获得了视图的宽度,并添加了150,因为我们现在向左移动了150 x轴,以使视图宽度为其原始宽度,而底部等于视图的高度。
希望您现在的人们理解翻译的概念,但仍然有任何问题可以在评论部分中立即提出,我很乐意提供帮助:)
编辑不要使用layout()方法,因为当视图无效并且您的更改将不存在时,框架可以调用该方法,请根据需要使用LayoutParams设置布局参数
Muhammad Babar answered 2019-10-13T23:09:19Z
79 votes
动画按预期工作。 仅仅因为您对某物进行了动画处理并不意味着您实际上在移动它。 动画仅在动画本身期间影响绘制的像素,而不影响小部件的配置。
您需要添加AnimationListener,然后在onAnimationEnd()方法中执行一些使您的移动永久化的操作(例如,从其父级移除顶部视图,将顶部视图标记为具有可见性GONE)。
CommonsWare answered 2019-10-13T23:07:33Z
22 votes
我的回复可能有点晚,但是我有解决方案:
只需添加android:fillAfter="true"在你的xml中
sreeram answered 2019-10-13T23:09:50Z
9 votes
您可以使用
fillAfter=true
fillEnabled=true
您的视图不会重置为原始位置,但是如果您的视图中有一些按钮或其他内容,它们的位置将不会改变。
您必须使用object animator,它从API 11级别开始起作用。 它会自动更改视图位置,
这是例子
ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(mContent_container, "translationX", startX, endX);
objectAnimator.setDuration(1000);
objectAnimator.start();
感谢JUL的回答
如果找不到您的应用程序object animator,请将API级别从Project -> properties -> Android更改为import android.animation.ObjectAnimator;
问候海克
Hayk Nahapetyan answered 2019-10-13T23:10:50Z
7 votes
您需要添加以下命令:
final Animation animSlideLeft = new TranslateAnimation(0, -80, 0,-350, 0, 0, 0, 0);
animSlideLeft.setFillAfter(true);
Wattanapong Suttapak answered 2019-10-13T23:11:15Z
1 votes
我去了同一个问题,并通过在OnAnimationEnd()处设置marginLeft解决了它。
MarginLayoutParams params = (MarginLayoutParams) this.getLayoutParams();
params.setMargins(this.getWidth()*position, 0,0,0);
this.setLayoutParams(params);
Lukas Olsen answered 2019-10-13T23:11:47Z
1 votes
这个问题困扰了一个多星期。穆罕默德的回答为我指出了解决这一难题的捷径。
我使用服务器布局来实现带有动画的侧菜单。“ view.layout不会是持久的。您应该使用LayoutParams,它将是持久的。”
这是我的解决方案:(使用哪种LayoutParameter取决于您自己父母的布局):
@Override
public void onAnimationEnd(Animation animation) {
FrameLayout.LayoutParams layoutParams=new FrameLayout.LayoutParams(screenWidth, screenHeight);
layoutParams.setMargins((int) -(screenWidth * RATE), 0,
(int) (screenWidth - screenWidth * RATE), screenHeight);
for(View v:views) {
v.setLayoutParams(layoutParams);
//v.layout((int) -(screenWidth * RATE), 0, (int) (screenWidth - screenWidth * RATE), screenHeight);
v.clearAnimation();
}
}
Ranger Way answered 2019-10-13T23:12:26Z
0 votes
使用下面的帮助方法可以轻松为您的视图添加动画。 然后,您可以像这样设置动画并在完成后重置:
// Animate the view:
fly(
view1,
(float) 0,
(float) 0,
(float) 0,
(float) 1000,
250,
null,
null,
() -> {
// Return the view to initial position on animation end:
fly(
view1,
(float) 0,
(float) 0,
(float) 0,
(float) 0,
0);
return null;
});
辅助方法:
/**
* Translation of a view.
*/
public static void fly(
View view,
float fromXDelta,
float toXDelta,
float fromYDelta,
float toYDelta,
int duration) {
fly(
view,
fromXDelta,
toXDelta,
fromYDelta,
toYDelta,
duration,
null,
null,
null);
}
/**
* Translation of a view with handlers.
*
* @param view A view to animate.
* @param fromXDelta Amount to shift by X axis for start position.
* @param toXDelta Amount to shift by X axis for end position.
* @param fromYDelta Amount to shift by Y axis for start position.
* @param toYDelta Amount to shift by Y axis for end position.
* @param duration Animation duration.
* @param start On animation start. Otherwise NULL.
* @param repeat On animation repeat. Otherwise NULL.
* @param end On animation end. Otherwise NULL.
*/
public static void fly(
View view,
float fromXDelta,
float toXDelta,
float fromYDelta,
float toYDelta,
int duration,
Callable start,
Callable repeat,
Callable end) {
Animation animation;
animation =
new TranslateAnimation(
fromXDelta,
toXDelta,
fromYDelta,
toYDelta);
animation.setDuration(
duration);
animation.setInterpolator(
new DecelerateInterpolator());
animation.setFillAfter(true);
view.startAnimation(
animation);
animation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
if (start != null) {
try {
start.call();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onAnimationEnd(Animation animation) {
if (end != null) {
try {
end.call();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onAnimationRepeat(
Animation animation) {
if (repeat != null) {
try {
repeat.call();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
Zon answered 2019-10-13T23:12:58Z