繁体   English   中英

Android-设置边距动画/一次更改多个视图的位置

[英]Android - Animate margin / change position of multiple views at once

我有一个并排的4个按钮的RelativeLayout。 在某些情况下,我希望通过动画更改位置/更改所有四个Button的边距。

我目前正在使用以下代码

final RelativeLayout.MarginLayoutParams params1 = (RelativeLayout.MarginLayoutParams) button1.getLayoutParams();
final RelativeLayout.MarginLayoutParams params2 = (RelativeLayout.MarginLayoutParams) button2.getLayoutParams();
final RelativeLayout.MarginLayoutParams params3 = (RelativeLayout.MarginLayoutParams) button3.getLayoutParams();
final RelativeLayout.MarginLayoutParams params4 = (RelativeLayout.MarginLayoutParams) button4.getLayoutParams();
final RelativeLayout.MarginLayoutParams params5 = (RelativeLayout.MarginLayoutParams) button5.getLayoutParams();

ValueAnimator animator1 = ValueAnimator.ofInt(params1.rightMargin, (deviceWidth - availableWithForTabs + spaceForTabs));
ValueAnimator animator2 = ValueAnimator.ofInt(params2.rightMargin, dpToPx(78));
ValueAnimator animator3 = ValueAnimator.ofInt(params3.rightMargin, dpToPx(52));
ValueAnimator animator4 = ValueAnimator.ofInt(params4.rightMargin, dpToPx(26));
ValueAnimator animator5 = ValueAnimator.ofInt(params5.rightMargin, dpToPx(0));

animator5.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        params5.rightMargin = (Integer) valueAnimator.getAnimatedValue();
    }
});
animator5.setDuration(150);
animator5.start();

animator4.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        params4.rightMargin = (Integer) valueAnimator.getAnimatedValue();
    }
);
animator4.setDuration(150);
animator4.start();

animator3.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        params3.rightMargin = (Integer) valueAnimator.getAnimatedValue();
    }
 });
 animator3.setDuration(150);
 animator3.start();

 animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
     @Override
     public void onAnimationUpdate(ValueAnimator valueAnimator) {
        params2.rightMargin = (Integer) valueAnimator.getAnimatedValue();
     }
 });
 animator2.setDuration(150);
 animator2.start();

 animator1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        params1.rightMargin = (Integer) valueAnimator.getAnimatedValue();
        button1.requestLayout();
    }
 });
animator1.setDuration(150);
animator1.start();

我觉得以上代码无法为5个按钮设置边距变化动画。 有人可以告诉我一种更好的方法吗? 还是我还有其他选择? 我必须支持SDK 16 +

您可能需要重新考虑您的设计,使用ViewPropertyAnimator可以为您节省很多代码行,并且可读性强/易于维护。

使用ViewPropertyAnimator非常简单:

Button button1 = (Button) findViewById(R.id.button1);
button1.animate()
       .translationX(toX)
       .translationY(toY)
       .setDuration(milliseconds);  // add more if you 
                                    // like (alpha, startDelay)                             
                                    // check the docs for available methods

动画总是从视图的当前位置开始。

为了使代码更简洁,为什么不尝试这样的操作:

编写自己的动画方法,该方法采用一个View(在您的情况下为Button),并将所有需要的值作为参数(在x和y轴上移动视图的最小实现):

private void animateView(View view, float toX, float toY, int duration) {
    view.animate()
        .translationX(toX)
        .translationY(toY)
        .setDuration(duration);
}

然后,您只需在按钮上调用此方法即可对它们进行单独动画处理fe:

animateView(button1, 5.0f, 2.5f, 150);
animateView(button2, 2.5f, 1.0f, 150);

当然5.0f,2.5f等只是虚构的数字,您必须填写要自行移动Views的位置。

额外建议:使用插值器使动画更像fe总是更好,这总是很高兴的:

view.animate()
    .translationX(...)
    .translationY(...)
    .setInterpolator(new AccelerateDecelerateInterpolator())
    .setDuration(...);

如果还不够彻底或不清楚,请告诉我。

更新:如果要设置侦听器,则可以在您的类中实现Animator.AnimatorListener接口,如下所示:

public class yourClass extends AppCompatActivity implements Animator.AnimatorListener {...

然后,您必须实施以下方法:

 @Override
 public void onAnimationEnd(Animator animation) {
 // here you can call stuff that should happen when the animation ends,
//     f.e. start the next animation
// the method names explain themselves 
 }
@Override
public void onAnimationStart(Animator animation) {

}

@Override
public void onAnimationCancel(Animator animation) {

}

@Override
public void onAnimationRepeat(Animator animation) {

}

然后,您要做的就是在animateView方法中添加另一行:

view.animate()
...
...
.setListener(this);

或者,您可以在这样的匿名内部类中进行操作:

view.animate()
...
...
.setListener(new Animator.AnimatorListener() {

    @Override
    public void onAnimationEnd(Animator animation) {

    }
     // same methods as above ...
    ...
)};

您为什么不只为包含4个按钮的整个相对布局设置动画。

我也建议使用View.animate方法

公共ViewPropertyAnimator动画()

在API级别12中添加。此方法返回一个ViewPropertyAnimator对象,该对象可用于为该View上的特定属性设置动画。

返回ViewPropertyAnimator与此视图关联的ViewPropertyAnimator。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM