从上到下的翻转动画

5

需要在 Android 2.2 及以上版本中制作以下动画:

1. 点击按钮后,将其从顶部移动到底部,

2. 再次点击按钮后,将其从底部移回顶部。

第一个动画效果良好,但第二个动画无法正常运行,按钮会“跳跃”而不是平稳的动画过渡。

代码:

public class MainActivity extends Activity {

static RelativeLayout relativeLayout;
static Button btn;
static Boolean isUp = true;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btn = (Button) findViewById(R.id.button1);
    relativeLayout = (RelativeLayout) findViewById(R.id.relative_layout);

    btn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            if(isUp){
                isUp = false;
                v.startAnimation(MainActivity.getVerticalSlideAnimation(0,relativeLayout.getBottom() - v.getHeight(),500,0));
            }else{
                isUp = true;
                v.startAnimation(MainActivity.getVerticalSlideAnimation(relativeLayout.getBottom() - v.getHeight(),0,500,0));
            }
        }
    });
}


public static Animation getVerticalSlideAnimation(int fromYPosition, final int toYPosition, int duration, int startOffset)
{
  TranslateAnimation translateAnimation = new TranslateAnimation(1, 0.0F, 1, 0.0F, 0, fromYPosition, 0, toYPosition);
  translateAnimation.setDuration(duration);
  translateAnimation.setInterpolator(new AccelerateInterpolator());
  translateAnimation.setStartOffset(startOffset);

  //Stop animation after finishing.
  //translateAnimation.setFillAfter(true);

  translateAnimation.setAnimationListener(new AnimationListener() 
  {
    public void onAnimationStart(Animation animation) { }
    public void onAnimationRepeat(Animation animation) { }
    public void onAnimationEnd(Animation animation) {
        btn.setY(toYPosition);          
    }
  });

  return translateAnimation;
    }
}

布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/relative_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:text="Button" />

</RelativeLayout>
2个回答

10

好的,我解决了。

关于动画,有几个问题需要您知道:

  1. 动画参数并不像您想的那样简单,即“从(固定位置)”——“到(固定位置)”。它们更像是“从(当前位置/0)”——“要执行多少步以及在哪个方向上(正号表示正方向/负号表示负方向)”

  2. 动画不会改变视图在屏幕上的真实位置,因此如果您想在结束位置停止动画,则应使用:

  3. animation.setFillAfter(true);
    
    如果你想要改变视图的真实位置,你应该在“onAnimationEnd”上更新视图参数(如下所示),或者手动计算位置并设置Y/X位置(同样在“onAnimationEnd”上),例如:
    animatedView.setY(stopPosition);
    

代码:

    public class AnimationActivity extends Activity {

    private boolean isUp;

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ((Button) findViewById(R.id.button1))
            .setOnClickListener(new OnClickListener() {

                public void onClick(final View v) {

                    final float direction = (isUp) ? -1 : 1;
                    final float yDelta = getScreenHeight() - (2 * v.getHeight());
                    final int layoutTopOrBottomRule = (isUp) ? RelativeLayout.ALIGN_PARENT_TOP : RelativeLayout.ALIGN_PARENT_BOTTOM;

                    final Animation animation = new TranslateAnimation(0,0,0, yDelta * direction);

                    animation.setDuration(500);

                    animation.setAnimationListener(new AnimationListener() {

                        public void onAnimationStart(Animation animation) {
                        }

                        public void onAnimationRepeat(Animation animation) {
                        }

                        public void onAnimationEnd(Animation animation) {

                            // fix flicking
                            // Source : https://dev59.com/NWox5IYBdhLWcg3wKBR9
                            TranslateAnimation anim = new TranslateAnimation(0.0f, 0.0f, 0.0f, 0.0f);
                            anim.setDuration(1);
                            v.startAnimation(anim);


                            //set new params
                            LayoutParams params = new LayoutParams(v.getLayoutParams());
                            params.addRule(RelativeLayout.CENTER_HORIZONTAL);
                            params.addRule(layoutTopOrBottomRule);
                            v.setLayoutParams(params);
                        }
                    });

                    v.startAnimation(animation);

                    //reverse direction
                    isUp = !isUp;
                }
            });
}

private float getScreenHeight() {

    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    return (float) displaymetrics.heightPixels;

}


这真的很有帮助。我想知道如何连续从上到下移动视图,并在每个步骤移动时获取其位置。如何使用动画实现它?是否还有其他方法可用?我的最终目的是检测移动视图与此视图之间的碰撞?感谢您的帮助。 - Ajay

-1
    public class AnimationActivity extends Activity {

    private boolean isUp;

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ((Button) findViewById(R.id.button1))
            .setOnClickListener(new OnClickListener() {

                public void onClick(final View v) {

                    final float direction = (isUp) ? -1 : 1;
                    final float yDelta = getScreenHeight() - (2 * v.getHeight());
                    final int layoutTopOrBottomRule = (isUp) ? RelativeLayout.ALIGN_PARENT_TOP : RelativeLayout.ALIGN_PARENT_BOTTOM;

                    final Animation animation = new TranslateAnimation(0,0,0, yDelta * direction);

                    animation.setDuration(500);

                    animation.setAnimationListener(new AnimationListener() {

                        public void onAnimationStart(Animation animation) {
                        }

                        public void onAnimationRepeat(Animation animation) {
                        }

                        public void onAnimationEnd(Animation animation) {

                            // fix flicking
                            // Source : https://dev59.com/NWox5IYBdhLWcg3wKBR9
                            TranslateAnimation anim = new TranslateAnimation(0.0f, 0.0f, 0.0f, 0.0f);
                            anim.setDuration(1);
                            v.startAnimation(anim);


                            //set new params
                            LayoutParams params = new LayoutParams(v.getLayoutParams());
                            params.addRule(RelativeLayout.CENTER_HORIZONTAL);
                            params.addRule(layoutTopOrBottomRule);
                            v.setLayoutParams(params);
                        }
                    });

                    v.startAnimation(animation);

                    //reverse direction
                    isUp = !isUp;
                }
            });
}

private float getScreenHeight() {

    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    return (float) displaymetrics.heightPixels;

}

你可以直接设置 onClickListener 而无需将其转换为 Button。 - Hamzeh Soboh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接