Top to bottom - translate animation

2019-05-01 19:08发布

Need to make next animation (on android 2.2 and above):

1.Moving button from top to bottom (after clicking on him),

2.Moving back from bottom to top (After clicking on him again).

First animation works fine, but the second not, the btn "jumps" from bottom to top and not animate.

Code:

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

Layout:

<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条回答
闹够了就滚
2楼-- · 2019-05-01 19:43
    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 : http://stackoverflow.com/questions/9387711/android-animation-flicker
                            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;

}
查看更多
淡お忘
3楼-- · 2019-05-01 19:54

Ok, I solved it.

There are few issuses you should know about animation:

  1. The animation paremeters are not simple "From (fixed position)" --> "To (fix position)" as you should think. There are more like "From (current position/0)" --> "How much steps to do and on which direction (pluse for positive/ minus for negative)"

  2. The Animation doesn't change the real position of the view on the screen, Therefore if you want to stop the animation at the end position, you should use:

    animation.setFillAfter(true);
    
  3. If you do want to change the REAL position of the view you should update the view parameters on "onAnimationEnd" (like below code), or calculate position and set Y/X position manually (again on "onAnimationEnd"), like:

    animatedView.setY(stopPosition);
    

The Code:

    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 : http://stackoverflow.com/questions/9387711/android-animation-flicker
                            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;

}

}

查看更多
登录 后发表回答