Android 如何动画视图的翻译
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11188338/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to animate a View's translation
提问by Adil Hussain
At the first click of a button, I want to slide a Viewalong the x-axis (by 200 pixels to the right let's say). And on the second press of the button, I want to slide the Viewback along the x-axis to its original position.
在第一次单击按钮时,我想View沿 x 轴滑动 a (比方说向右 200 像素)。在第二次按下按钮时,我想将View背面沿 x 轴滑动到其原始位置。
The View.setTranslationX(float)method jumpsthe View to the target horizontal locations with calls myView.setTranslationX(200);and myView.setTranslationX(0);respectively. Anyone know how I can slidethe Viewto the target horizontal locations instead?
该View.setTranslationX(float)方法分别调用和将 View跳转到目标水平位置。任何人都知道我怎么能滑动的,而不是目标的水平位置?myView.setTranslationX(200);myView.setTranslationX(0);View
Note 1:A
TranslateAnimationis no good since it doesn't actually move theViewbut only presents the illusion of it moving.Note 2:I didn't realise at the time of posing the question that the
setTranslationX(float)andsetTranslationY(float)methods were introduced as of API Level 11. If you're targeting Honeycomb (API Level 11) upwards, then Gautam K's answer will suffice. Otherwise, see my answer for a suggested solution.
注 1:A
TranslateAnimation不好,因为它实际上并没有移动,View而只是呈现了它在移动的错觉。注 2:在提出问题时我没有意识到
setTranslationX(float)和setTranslationY(float)方法是从 API 级别 11 开始引入的。如果您的目标是 Honeycomb(API 级别 11)向上,那么 Gautam K 的回答就足够了。否则,请参阅我的答案以获取建议的解决方案。
采纳答案by Adil Hussain
This one's had me stumped for a fair few days (getting it to work pre- Ice Cream Sandwich) but I think I've finally got there! (thanks to Gautam K and Mike Israel for the leads) What I did in the end was to extend my View(a FrameLayout) to start the translate right/left animations as required and to listen for the end of the animations in order to relocate my FrameLayoutright/left as appropriate, as follows:
这个让我难倒了好几天(让它在冰淇淋三明治之前工作)但我想我终于到了那里!(感谢 Gautam K 和 Mike Israel 的指导)我最后所做的是扩展我的View(a FrameLayout) 以根据需要开始翻译右/左动画并监听动画结束以重新定位我的FrameLayout右/left 视情况而定,如下:
public class SlidingFrameLayout extends FrameLayout
{
private final int durationMilliseconds = 1000;
private final int displacementPixels = 200;
private boolean isInOriginalPosition = true;
private boolean isSliding = false;
public SlidingFrameLayout(Context context)
{
super(context);
}
public SlidingFrameLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public SlidingFrameLayout(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
@Override
protected void onAnimationEnd()
{
super.onAnimationEnd();
if (isInOriginalPosition)
offsetLeftAndRight(displacementPixels);
else
offsetLeftAndRight(-displacementPixels);
isSliding = false;
isInOriginalPosition = !isInOriginalPosition;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
{
super.onLayout(changed, left, top, right, bottom);
// need this since otherwise this View jumps back to its original position
// ignoring its displacement
// when (re-)doing layout, e.g. when a fragment transaction is committed
if (changed && !isInOriginalPosition)
offsetLeftAndRight(displacementPixels);
}
public void toggleSlide()
{
// check whether frame layout is already sliding
if (isSliding)
return; // ignore request to slide
if (isInOriginalPosition)
startAnimation(new SlideRightAnimation());
else
startAnimation(new SlideLeftAnimation());
isSliding = true;
}
private class SlideRightAnimation extends TranslateAnimation
{
public SlideRightAnimation()
{
super(
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, displacementPixels,
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, 0);
setDuration(durationMilliseconds);
setFillAfter(false);
}
}
private class SlideLeftAnimation extends TranslateAnimation
{
public SlideLeftAnimation()
{
super(
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, -displacementPixels,
Animation.ABSOLUTE, 0,
Animation.ABSOLUTE, 0);
setDuration(durationMilliseconds);
setFillAfter(false);
}
}
}
And, lastly, to slide the SlidingFrameLayoutright/left, all you've got to do is call the SlidingFrameLayout.toggleSlide()method. Of course you can tweak this SlidingFrameLayoutfor your purposes to slide a greater number of pixels, to slide for longer etc, but this should be sufficient to get you started :)
最后,要SlidingFrameLayout向右/向左滑动,您所要做的就是调用该SlidingFrameLayout.toggleSlide()方法。当然,您可以SlidingFrameLayout根据自己的目的调整它以滑动更多像素,滑动更长时间等,但这应该足以让您开始:)
回答by Gautam
Try looking into ObjectAnimatorand its super class Value Animator
尝试查看ObjectAnimator及其超类 Value Animator
you can do something like this
ObjectAnimator anim = ObjectAnimator.ofFloat(this, "translationX", 0,200);and then
anim.start();
你可以做这样的事情
ObjectAnimator anim = ObjectAnimator.ofFloat(this, "translationX", 0,200);然后
anim.start();
Use a booleanvalue and toggle it with 200,0in the object animator to slide back
使用一个boolean值并200,0在对象动画器中切换它以向后滑动
PS: you can use setDurationmethod to set how long the animation should take to complete
PS:您可以使用setDuration方法来设置动画需要多长时间才能完成
Edit :
编辑 :
Try looking at the support librarywhich provides backward compatibility.
尝试查看提供向后兼容性的支持库。
Edit
编辑
As @AdilHussain pointed out there is a library called nineoldandroidswhich can be used for the same purpose on older androids.
正如@AdilHussain 指出的那样,有一个名为Nineoldandroids的库,可用于旧机器人上的相同目的。
回答by MikeIsrael
I had a similar issue, TranslateAnimation does actually move the view if you call setFillAfter now (android bug). I had to do something similar so I said, hey lets use an animation listener and then just move everything to the correct location. Unfortunately there is a bug on animation listeners as well (stackoverflow solution). So I created my own layout class according to the solution in the stackoverflow solutionand I was good to go :)
我有一个类似的问题,如果你现在调用 setFillAfter ( android bug) ,TranslateAnimation 实际上会移动视图。我不得不做类似的事情,所以我说,嘿,让我们使用动画侦听器,然后将所有内容移动到正确的位置。不幸的是,动画侦听器也存在错误(stackoverflow 解决方案)。所以我根据stackoverflow解决方案中的解决方案创建了自己的布局类,我很高兴:)

