开发者

Android Slide Animation Flashing

开发者 https://www.devze.com 2023-04-12 16:51 出处:网络
I am trying to animate an ImageButton. When the button is clicked, I want it to slide to the right. When it\'s clicked again, it should slide back to its original position.

I am trying to animate an ImageButton. When the button is clicked, I want it to slide to the right. When it's clicked again, it should slide back to its original position.

When the animation ends it goes back to the original position therefore I reposition the ImageButton. I have a small "flash" where both the ImageButton and the animation is at the original position before the ImageButton has been repositioned. Can anyone tell me how to get rid of this "flash"?

I have written the following code to start the animations and when the animation ends, move the ImageButton itself. What it is, is an onClickListener for sliding the ImageButton in and an AnimationListener for this. There's also an onClickListener and an AnimationListener for sliding the ImageButton back.

private class SceneIndicatorListenerIn implements ImageButton.OnClickListener {
    ImageButton imageButton;
    public SceneIndicatorListenerIn (ImageButton imageButton) {
        this.imageButton = imageButton;
    }

    @Override
    public void onClick(View view) {
        // Create animation
        Animation anim = AnimationUtils.loadAnimation(context, R.anim.sceneindicator_in);
        anim.setAnimationListener(new SceneIndicatorListenerInDidEnd(imageButton));
        view.startAnimation(anim);
    }
}

private class SceneIndicatorListenerInDidEnd implements AnimationListener {
    ImageButton imageButton;
    public SceneIndicatorListenerInDidEnd (ImageButton imageButton) {
        this.imageButton = imageButton;
    }

    @Override
    public void onAnimationEnd(Animation anim) {
        Log.d(LOG_TAG, "In animation did end");

        // This is for density pixels
        float dp = context.getResources().getDisplayMetrics().density;

        // Keep position after animation
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(imageButton.getWidth(), imageButton.getHeight());
        params.setMargins((int) (0 * dp), imageButton.getTop(), 0, 0);
        imageButton.setLayoutParams(params);

        // Change on click listener
        imageButton.setOnClickListener(new SceneIndicatorListenerOut(imageButton));
    }

    @Override
    public void onAnimationRepeat(Animation arg0) {}

    @Override
    public void onAnimationStart(Animation arg0) {}
}

private class SceneIndicatorListenerOut implements ImageButton.OnClickListener {
    ImageButton imageButton;
    public SceneIndicatorListenerOut (ImageButton imageButton) {
        Log.d(LOG_TAG, "My imageButton was set");
        this.imageButton = imageButton;
    }

    @Override
    public void onClick(View view) {
        Log.d(LOG_TAG, "You clicked me");

        // Create animation
        Animation anim = AnimationUtils.loadAnimation(context, R.anim.sceneindicator_out);
        anim.setAnimationListener(new SceneIndicatorListenerOutDidEnd(imageButton));
        view.startAnimation(anim);
    }
}

private class SceneIndicatorListenerOutDidEnd implements AnimationListener {
    ImageButton imageButton;
    public SceneIndicatorListenerOutDidEnd (ImageButton imageButton) {
        this.imageButton = imageButton;
    }

    @Override
    public void onAnimationEnd(Animation anim) {
        Log.d(LOG_TAG, "Out animation did end");

        // This is for density pixels
        float dp = context.getResources().getDisplayMetrics().density;

        // Keep position after animation
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(imageButton.getWidth(), imageButton.getHeight());
        params.setMargins((int) (-199 * dp), imageButton.getTop(), 0, 0);
        imageButton.setLayoutParams(params);

        // Change on click listener
        imageButton.setOnClickListener(new SceneIndicatorListene开发者_如何学PythonrIn(imageButton));
    }

    @Override
    public void onAnimationRepeat(Animation arg0) {}

    @Override
    public void onAnimationStart(Animation arg0) {}
}

This is my animation for sliding in:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0%"
               android:toXDelta="83%"
               android:duration="750" />
</set>

And this is my animation for sliding back:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0%"
               android:toXDelta="-80%"
               android:duration="750" />
</set>


I had this same issue and wanted to post the answer for anyone who encounters this. There is a bug that causes this no matter what you set in xml or otherwise.

The way I got around it was the manually set the X location off of the screen before the animation so that the flash would happen off of the screen, then it would be set back to it's original position as being processed by the animation.

image.setX(-5000);//Really any number off of the screen will do

Animation animation0 = AnimationUtils.loadAnimation(this,
            R.anim.slide_across_right);
animation0.setAnimationListener(new AnimationListener() {

        @Override
        public void onAnimationStart(Animation animation) {
            animationHack();
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationEnd(Animation animation) {
        }
});



private void animationHack() {
    (new Handler()).postDelayed(new Runnable() {
        public void run() {
            image.setX(0);
        }
    }, 20);

}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号