[英]Android View with a translate animation - positioning is not working as expected
我有一个具有OnClickListener
的视图。 单击后,视图将平移到页面上的特定位置。 这是没有问题的,视图可以到达应有的位置。 当再次单击该视图时,我想将其放置在其他位置,但事实并非如此。 经过一番排查后,我发现我的View的getTop()方法返回了相同的值-即使在平移动画将视图移动到屏幕的不同部分之后也是如此。 对于第二个动画,它不使用当前位置(正如我期望的那样),而是使用初始位置。
我正在做的一些事情:我使用的是ObjectAnimation
类而不是TranslationAnimation
类,因为我想保持OnClickListener
功能。 使用TranslationAnimation
类,我发现视图已正确移动,但是OnClickListener
仅在View所在的区域中工作。 使用ObjectAnimation
类,我可以轻松地使翻译正常工作,并且OnClickListener
功能正确-在屏幕上当前视图的位置触发它。
这是我到目前为止的内容:
final LinearLayout child = layouts.get(i); //ArrayList containing some dynamic layouts
final int offset = target - child.getTop();
ObjectAnimator anim = ObjectAnimator.ofFloat(child,"translationY",offset);
anim.setDuration(250);
anim.start();
这是第一次单击视图时发生的情况。 它沿Y轴向上平移,其中的偏移量确定了View需要从其当前位置移动多远。
现在,这是第二次点击发生的情况。 这里的目标是使视图与父母的基础对齐。
target = parent.getBottom();
offset = target - child.getTop();
anim = ObjectAnimator.ofFloat(child, "translationY",offset);
anim.setDuration(250);
anim.start();
prev = child;
这就是一切的地方child.getTop()
返回视图原始位置的Y坐标。 不是当前位置。 因此,在动画之后,将视图放置在父级底部的下方。 我读了一个不同的问题,该问题表明我应该改用child.getY()
,这应该使我获得translationY
位置加上top
位置,但这并没有带来更好的结果。 我似乎无法正常工作。 我只是想将视图从当前位置移动到屏幕底部,但这似乎很难完成。 任何帮助,将不胜感激。
编辑
我添加了一个动画监听器:
ObjectAnimator anim = ObjectAnimator.ofFloat(child,"translationY",offset);
anim.setDuration(250);
anim.addListener(new ObjectAnimator.AnimatorListener(){
@Override
public void onAnimationStart(Animator animation) {
System.out.println("start: " + child.getTop() + " " + child.getY());
}
@Override
public void onAnimationEnd(Animator animation) {
System.out.println("end: " + child.getTop() + " " + child.getY() + " " + child.getTranslationY());
child.setTop((int)child.getY());
System.out.println(child.getTop());
}
@Override
public void onAnimationCancel(Animator animation) {}
@Override
public void onAnimationRepeat(Animator animation) {}
});
anim.start();
在这里,我设置侦听器以尝试更改视图顶部的位置。 行为再次无法正常工作。 当我这样做时,视图实际上是在屏幕上方发送的。 System.out的输出如下所示:
start: 2008 2008.0
end: 2008 478.0 -1530.0
478
因此,在动画完成并设置新位置后调用child.getTop()
返回一个正整数,但是视图实际上并没有完全显示在屏幕上。 它在屏幕上方,部分可见。 视图本身的高度约为700像素。 我仍然很困惑为什么这很难完成。
编辑2
我也尝试过在onAnimationEnd
方法中设置layoutparams:
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)child.getLayoutParams();
params.removeRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
params.topMargin = (int)child.getY();
child.setLayoutParams(params);
结果: child.getTop()
仍返回2008的原始位置。
您可以像这样获得屏幕底部的坐标:
float bottomOfScreen = getResources().getDisplayMetrics().heightPixels;
但您可能希望它减去LinearLayout的高度,否则LinearLayout会被底部截断:
float bottomOfScreen = getResources().getDisplayMetrics().heightPixels
- child.getHeight();
// if you want a little more space to the bottom
// try something like - child.getHeight()*2;
然后使用ViewPropertyAnimator对LL进行动画处理,如下所示:
child.animate()
.translationY(bottomOfScreen)
.setInterpolator(new AccelerateDecelerateInterpolator())
.setDuration(250);
插值器只是为了使动画更加逼真。
如果child.getHeight()返回0,则系统尚未完成线性布局的设置,在这种情况下,您可能需要执行以下操作:
child.post(new Runnable() {
@Override
public void run() {
float bottomOfScreen = getResources().getDisplayMetrics().heightPixels
- child.getHeight()*2;
child.animate()
.translationY(bottomOfScreen)
.setInterpolator(new AccelerateDecelerateInterpolator())
.setDuration(250);
}
});
请记住,250毫秒的持续时间非常快,通常不会在屏幕上平移翻译内容,因此您可能需要将其设置得更高一些,但这仅是口味问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.