在最终animation位置保持animation视图

所以我使用animation来激活视图:

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator" > <translate android:duration="1000" android:fromYDelta="0%" android:toYDelta="-75%" /> </set> 

它在视觉上做我想要的,但我也想冻结这个animation的结果。 就像我需要以某种方式得到结果布局参数(或其他东西?)animation后,并将其设置为布局。 假设Y坐标的布局从0变为100,但是我并不知道什么是坐标,什么是坐标。 我需要得到结果的坐标,并将其设置为布局因为如果不这样做布局返回到animation后的初始位置,但我需要使它保持在新位置,而不是返回。 另外我需要2.3.x兼容的解决scheme。
更新1
我也试过NineOldAndroids:

 ObjectAnimator.ofFloat(rootWrapper, "translationY", -rootWrapper.getHeight()*75/100).start(); 

这animation视图和视图停留在animation位置 – 这正是我想要实现的。
然而,所有的控制都在虚拟的位置上。 即使你的布局只能看到其底部的25%,如果我点击那个空白的屏幕区域,那么75%的剩余屏幕看起来是空的,然后onClick触发button的(这是b4animation)。 如果设置了xml-animtaions,也会发生同样的情况

 animation.setFillAfter(true); 

如何解决这个问题? 所有的控件必须随着视图移动。
更新2
代码:

  public void showAbout(){ final Animation animShow = AnimationUtils.loadAnimation(this, R.anim.about_in_from_bottom); animShow.setFillAfter(true); //ObjectAnimator.ofFloat(rootWrapper, "translationY", -rootWrapper.getHeight()*75/100).start(); animShow.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { LinearLayout.LayoutParams rootlp = (LinearLayout.LayoutParams) rootWrapper.getLayoutParams(); Log.i(this,"rootlp: h: "+rootlp.topMargin+ " / w: "+rootlp.bottomMargin); rootlp.topMargin = -rootlp.height*75/100; rootWrapper.setLayoutParams(rootlp); } }); rootWrapper.startAnimation(animShow); } 

我得到了问题 – rootlp.height返回0 cuz它像MATCH_PARENT或类似。 它不会返回REAL像素,但代表一些常量的一些值! 所以看起来我有2玩.getViewTreeObserver().addOnGlobalLayoutListener
好的,我通过getViewTreeObserver()获得了rootWrapper的真正高度。 现在使用公式rootlp.topMargin = -rootlp.height*75/100; 我得到更多的问题。
1)animationView之后,另外移动(由于设置LP)。
2)animation视图包含的控件(必须与父视图一起向上移动的button)虚拟地停留在它们的位置(它们是不可见的,但是可点击的)! 在视觉上,这些控件是animation视图,我无法达到它(它离开了屏幕)。 但是,如果我点击区域,他们之前animation相应onClick()触发! 太好玩了!
更新3
最后我达到了我的目标! 问题是移动View的子容器。 我在想,如果我移动一些视图,那么所有的子视图也在移动。 但事实并非如此,我不得不在animation完成后手动移动子视图来修复幽灵button。

Related of "在最终animation位置保持animation视图"

请考虑setFillAfter(boolean); 将其设置为true将使视图停留在animation位置。

 Animation anim = new TranslateAnimation(0, 0, 0, 100); // or like this Animation anim = AnimationUtils.loadAnimation(this, R.anim.animation_name); anim.setFillAfter(true); anim.setDuration(1000); 

使用API​​ 14及以后版本的ViewPropertyAnimator可以更轻松地完成此操作:

 int animationpos = 500; View.animate().y(animationpos).setDuration(1000); // this will also keep the view at the animated position 

或者考虑一个AnimationListener在animation之后精确地获取LayoutParams:

 anim.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationRepeat(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { // get layoutparams here and set it in this example your views // parent is a relative layout, please change that to your desires RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) View.getLayoutParams(); lp.topMargin = yournewtopmargin // use topmargin for the y-property, left margin for the x-property of your view View.setLayoutParams(lp); } }); View.startAnimation(anim); 

更新:

如何知道视图移动了多less像素,取决于animation的百分比值?

.xmlanimation中的百分比值与animation视图的尺寸(如宽度和高度)相关。 因此,你只需要使用你的视图的宽度和高度属性 (取决于天气你使用x或yanimation来获得实际的animation距离像素)。

例如:

您的视图的宽度为400像素。 您的animation将x属性从0%animation到75%,这意味着您的视图将300像素(400 * 0.75)移动到右侧。 所以onAnimationEnd(),将LayoutParams.leftMargin设置为300,您的视图将具有所需的位置。

我发现只要将fillEnabled和fillAfter设置为TRUE,并不能解决涉及点击/触摸侦听器等问题。 设置填充启用和填充后才是正确的,只是确保视图的像素是在正确的最终位置DRAWN。 但是,假设正在animation的视图有一个与之关联的onclick监听器。 在新的可见位置单击视图将不会执行任何操作,但是单击视图最初位置的屏幕将触发onClick。

以下是一个如何解决这个问题的例子:

假设我们有一个onClickListener设置的视图。 假设视图范围是0,0,0,0(左,上,右,下)。 现在假设我们希望将视图向右移动200.下面的代码将演示如何以将要绘制的像素和底层视图对象移动到正确位置的方式来执行此操作,从而将onClick从正确的位置调用。

 private Animation generateMoveRightAnimation() { final Animation animation = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 200, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0); animation.setDuration(300); animation.setFillAfter(true); animation.setFillEnabled(true); animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view.getLayoutParams(); // change the coordinates of the view object itself so that on click listener reacts to new position view.layout(view.getLeft()+200, view.getTop(), view.getRight()+200, view.getBottom()); repeatLevelSwitch.clearAnimation(); } @Override public void onAnimationRepeat(Animation animation) { } }); return animation; } 

您可以根据需要使用NineOldAndroid代理库来使用ObjectAnimator。 它支持较低的API级别,并使用本机库更新的API级别。

只需简单地导入为LibraryProject,它会很好。