将动画视图保持在最终动画位置 [英] Keep animated View at final Animation Position

查看:30
本文介绍了将动画视图保持在最终动画位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在使用动画为视图设置动画:

So I'm animating a view using 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>

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

It does visually what I want but I also I want to freeze result of this animation. Like I need somehow to get resulting layout parameters (or something else?) after animation and set it to layout. Assume layout Y-coord is changing from 0 to 100 but I don't really know what was starting coords and what are resulting coords. I need to get resulting coords and set it to the layout cuz if wouldn't do so layout returns back to its initial position after animation but I need to make it stay in new position instead of returning back. Also I need 2.3.x compatible solution.
UPDATE 1
I also tried NineOldAndroids:

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

这使视图动画化,并且视图停留在动画位置——这正是我想要实现的.
然而,所有控件实际上都停留在它们的位置.即使您的布局仅在其底部的 25% 可见,如果我点击该空白屏幕区域,则其余屏幕的 75% 看起来是空的,然后按钮(有 b4 动画)的 onClick 触发.如果设置了 xml-animtaions 也会发生同样的情况

this animates the view and view stays at animated position - thats exactly what I want to achieve.
However all controls stays at their positions virtually. Even thou layout is only visible by 25% of its bottom part and 75% of rest screen looks empty if I tap that empty screen area then button's (which was there b4 animation) onClick triggered. The same happens with xml-animtaions if set

animation.setFillAfter(true); 

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

How to fix that issue? All controls has to move with the view.
UPDATE 2
The code:

    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 因为它像 MATCH_PARENT 或类似.它不会返回真正的像素,而是一些代表某个常数的值!所以看起来我有 2 个 .getViewTreeObserver().addOnGlobalLayoutListener.
好的,我通过 getViewTreeObserver() 得到了 rootWrapper 的真实高度.现在使用公式 rootlp.topMargin = -rootlp.height*75/100; 我遇到了更多问题.
1) 动画后视图额外上移(由于设置 LP).
2) 动画视图包含的控件(必须与父视图一起向上移动的按钮)几乎保持在它们的位置(它们不可见但可点击)!视觉上,这些控件随着动画视图向上移动,我无法触及它(它离开屏幕).但是,如果我在动画对应的 onClick() 触发之前点击它们所在的区域!真有趣!
更新 3
终于达到了我的目的!问题在于移动 View 的子容器.我在想,如果我移动一些 View,那么它的所有子视图也会移动.但事实并非如此,我不得不在动画完成后手动移动子视图以修复重影按钮.

I got the problem - rootlp.height returns 0 cuz its like MATCH_PARENT or like. It wont return the REAL pixels but some value representing some constant! So it looks like I have 2 play with .getViewTreeObserver().addOnGlobalLayoutListener.
Ok, I got the real height of rootWrapper via getViewTreeObserver(). And now using the formula rootlp.topMargin = -rootlp.height*75/100; I'm getting even more issues.
1) After animation View moves up additionally (due to setting LP).
2) Controls that animated View contains (buttons which has to move up with the parent View) stays at their positions virtually (they are invisible but clickable)! Visually those controls are moved up with the animated View and I can't reach it (it goes off the screen). But if I tap area where they was before animation corresponding onClick() triggers! What a fun!
UPDATE 3
Finally I had achieved my goal! The problem was with moving View's child containers. I was thinking that if I move some View then all of its child views are also moving. But thats not the case and I was had to move child views manually after animation completes to fix ghost buttons.

推荐答案

请考虑 setFillAfter(boolean); 将其设置为 true 会使视图停留在动画位置.

Please consider setFillAfter(boolean); setting it to true will make the view stay at the animated position.

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);

使用 ViewPropertyAnimator 可以更轻松地完成此操作,API 14 及更高版本提供:

This can be done even easier using the ViewPropertyAnimator, available from API 14 and onwards:

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

或者考虑使用 AnimationListener 来在动画之后获取 LayoutParams:

Or consider an AnimationListener to get the LayoutParams exactly after the animation:

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);

更新:

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

How to know how many pixels the view moved, depending on the percentage values of the animation?

.xml 动画中的百分比值与动画视图的尺寸(例如宽度和高度)相关.因此,您只需要使用视图的宽度和高度属性(取决于天气,您使用 x 或 y 动画来获取以像素为单位的实际动画距离).

The percentage value in your .xml animation is relative to the animated View's dimensions (such as width and height). Therefore, you just need to use your View's width and height properties (depending on weather u use x or y animation to get the actual animation distance in pixels).

例如:

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

Your View has a width of 400 pixels. Your animation animates the x-property from 0% to 75%, meaning that your view will move 300 pixels (400 * 0.75) to the right side. So onAnimationEnd(), set the LayoutParams.leftMargin to 300 and your View will have the desired position.

这篇关于将动画视图保持在最终动画位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆