Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/210.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有平移动画的Android视图-定位未按预期工作_Android_Animation - Fatal编程技术网

带有平移动画的Android视图-定位未按预期工作

带有平移动画的Android视图-定位未按预期工作,android,animation,Android,Animation,我有一个视图,它有一个OnClickListener。单击时,视图将转换到页面上的某个位置。这没问题,视图应该放在哪里就放在哪里。再次单击视图时,我希望将其放置在其他位置,但实际情况并非如此。经过一点故障排除,我发现我的视图的getTop()方法返回相同的值——即使在翻译动画将视图移动到屏幕的不同部分之后也是如此。对于第二个动画,它没有使用当前位置(正如我所期望的那样),而是使用初始位置 我现在做的事情很少:我使用的是ObjectAnimation类,而不是TranslationAnimatio

我有一个视图,它有一个
OnClickListener
。单击时,视图将转换到页面上的某个位置。这没问题,视图应该放在哪里就放在哪里。再次单击视图时,我希望将其放置在其他位置,但实际情况并非如此。经过一点故障排除,我发现我的视图的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轴向上平移,其中偏移确定视图需要从其当前位置移动多远

现在,下面是第二次单击时发生的情况。这里的目标是将视图与父对象的基础对齐

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年的原始位置。

您可以获得屏幕最底部的坐标,如下所示:

float bottomOfScreen = getResources().getDisplayMetrics().heightPixels;
child.animate()
    .translationY(bottomOfScreen)
    .setInterpolator(new AccelerateDecelerateInterpolator())
    .setDuration(250);
但您可能希望它减去直线布局的高度,否则直线布局将被底部截断:

float bottomOfScreen = getResources().getDisplayMetrics().heightPixels
                    - child.getHeight();

 // if you want a little more space to the bottom
    // try something like - child.getHeight()*2; 
然后,使用以下命令设置动画:

float bottomOfScreen = getResources().getDisplayMetrics().heightPixels;
child.animate()
    .translationY(bottomOfScreen)
    .setInterpolator(new AccelerateDecelerateInterpolator())
    .setDuration(250);
插值器只是为了使动画更逼真

如果child.getHeight()返回0,则系统尚未完成线性布局的设置,在这种情况下,您可能需要执行以下操作:

child.post(new Runnable() {
        @Override
        public void run() {
            float bottomOfScreen = getResources().getDisplayMetrics().heightPixels
                    - child.getHeight()*2;
            child.animate()
                    .translationY(bottomOfScreen)
                    .setInterpolator(new AccelerateDecelerateInterpolator())
                    .setDuration(250);
        }
    });

请记住,250毫秒的持续时间非常快,而且在屏幕上翻译内容通常看起来并不酷,因此您可能希望将其设置得更高一点,但这只是口味的问题。

这不符合预期。例如,我将位置从A设置为B,然后尝试将视图(在第一个动画完成后单击按钮)从B移动到C。我调用
child.animate().translationY(0).setInterpolator(新的AcceleratedAccelerateInterpolator()).setDuration(250)。这会将视图移回其原始位置。这毫无意义,因为
translationY()
应该将视图转换到指定的浮动位置。
translationY(0)
是否应该将视图移动到屏幕顶部?取而代之的是,它被送回了它开始的地方。