【发布时间】:2017-08-03 16:31:56
【问题描述】:
我有一个具有OnClickListener 的视图。单击时,视图会平移到页面上的某个位置。这没问题,视图在它应该去的地方。再次单击视图时,我想将其放置在其他位置,但事实并非如此。经过一些故障排除后,我发现我的 View 的 getTop() 方法返回相同的值 - 即使在翻译动画将视图移动到屏幕的不同部分之后也是如此。对于第二个动画,它没有使用当前位置(如我所料),而是使用初始位置。
我正在做的几件事:我使用ObjectAnimation 类而不是TranslationAnimation 类,因为我想保持OnClickListener 正常工作。使用TranslationAnimation 类,我发现视图已正确移动,但OnClickListener 仅在视图开始的区域中工作。使用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()会返回一个正整数,但视图实际上并没有完全显示在屏幕上。它位于屏幕上方,部分可见。视图本身的高度约为 700px。我仍然很困惑,为什么这是一件很难完成的事情。
编辑 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 的原始位置。
【问题讨论】: