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 View
along 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 View
back 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 View
to the target horizontal locations instead?
该View.setTranslationX(float)
方法分别调用和将 View跳转到目标水平位置。任何人都知道我怎么能滑动的,而不是目标的水平位置?myView.setTranslationX(200);
myView.setTranslationX(0);
View
Note 1:A
TranslateAnimation
is no good since it doesn't actually move theView
but 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 FrameLayout
right/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 SlidingFrameLayout
right/left, all you've got to do is call the SlidingFrameLayout.toggleSlide()
method. Of course you can tweak this SlidingFrameLayout
for 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 boolean
value and toggle it with 200,0
in the object animator to slide back
使用一个boolean
值并200,0
在对象动画器中切换它以向后滑动
PS: you can use setDuration
method 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解决方案中的解决方案创建了自己的布局类,我很高兴:)