AggieDev
AggieDev

Reputation: 5045

overridePendingTransition() isn't working

I am trying to implement a quick SplashActivity that slides in from the right to the left, then slides out to the left as the MainActivity slides in to the right. Currently, the animation XMLs are in place but it isn't working, the splash screen just appears, then the transition to the main activiity doesn't work either. Here is the SplashActivity that is the beginning activity of the app.

public class SplashActivity extends Activity{

    private int SPLASH_MILLISECONDS = 1000;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
        setContentView(R.layout.activity_splash);
        runTimer();
    }

    private void runTimer() {
        Timer timeout = new Timer();
        timeout.schedule(new TimerTask()
        {
            @Override
            public void run() 
            {                       
                runOnUiThread(new Runnable(){
                    @Override
                    public void run() {
                        goToMainActivity();
                    }
                });
            }                           
        }, SPLASH_MILLISECONDS);
    }

    private void goToMainActivity(){
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION );
        startActivity(intent);
        finish();
        overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);    
    }
}

This for some reason does not work, what is it I am doing wrong?

EDIT: This is my new goToMainActivity() method, yet still neither of the 2 animations are working. At this point I don't care much about the first animation working, I just want the second one working.

private void goToMainActivity(){
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);    
        finish();
    }

Upvotes: 5

Views: 14446

Answers (6)

Sam
Sam

Reputation: 3485

So if understand your problem correctly - you have two animations you want:

  1. An animation for the splash screen as it loads

  2. An animation from the splash screen to your main activity

And the seconds is working but the first is not. (the existing answer seems to be addressing the latter)

The problem:

overridePendingTransition() is supposed to be called IMMEDIATELY after a call to start activity (see here: http://developer.android.com/reference/android/app/Activity.html#overridePendingTransition(int, int) ) . This is why your second animation is working. In your first you are using it long after the call to startActivity which was done by the system.

As I see it there are two possibilities to fix this:

  1. Use another blank activity and launch that then slide from that to your current activity

  2. Use another kind of animation in your main activity

I think the second will be simpler for you to try. Googling around I found some examples of starting activities with an animation e.g. Android: start the app with animation

So we can adapt this to use a translate animation (http://developer.android.com/reference/android/view/animation/TranslateAnimation.html) (now tested - not the animation is set up in onResume()):

@Override
protected void onResume()
{
    super.onResume();
    FrameLayout layout = (FrameLayout) findViewById(R.id.splashRoot); //HERE USE YOUR ROOT LAYOUT
    WindowManager wm = getWindowManager();
    Display display = wm.getDefaultDisplay();
    Point outSize = new Point();
    display.getSize(outSize);
    int width = outSize.x;
    Animation moveRighttoLeft = AnimationUtils.loadAnimation(this, R.anim.right_slide_in);
    //apply the animation
    layout.startAnimation(moveRighttoLeft);
}

Where splashRoot is a view inside of a parent view that has your desire background color:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
tools:context="uk.co.airsource.android.common.examples.boundservicetest.app.Splash">

<FrameLayout
    android:id="@+id/splashRoot"
    android:background="#0099cc"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- The primary full-screen view. This can be replaced with whatever view
         is needed to present your content, e.g. VideoView, SurfaceView,
         TextureView, etc. -->

</FrameLayout>

also adapted this from here: Translate animation to correct position in Android

I think that no matter what you will end up with some animation from the system when your app starts - the system has certain animations for switching to different tasks that I don't know of any way to override.

UPDATE: I take that last sentence back. You can use your app theme to override animations, see here: How to override the enter activity animation if it is stated by launcher But also read carefully over 'hackbod's warnings

Edit: I tested my suggestion and added a few things above. I also uploaded the full working example activity (I actually added a splash screen to an existing example app I had) here: https://github.com/samskiter/BoundServiceTest/tree/splash

Upvotes: 1

0101100101
0101100101

Reputation: 5911

As far as I know you just have to put

overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);

inside MainActivity, not SplashActivity. Always works for me.

Edit: Actually, I just saw that you're extending Activity. I suppose you're not using the support library? Then animations like

<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
    android:duration="@android:integer/config_mediumAnimTime"
    android:fromXDelta="100%p"
    android:toXDelta="0" />
</set>

wouldn't work, but ObjectAnimators would.

Upvotes: 1

j__m
j__m

Reputation: 9645

i typically override the animation from within the onCreate() function of the activity being started, and this seems to work well. the caller should just startActivity() normally; don't use overridePendingTransition() or FLAG_ACTIVITY_NO_ANIMATION or anything else.

copied & pasted from actual deployed code:

@Override public void onCreate(Bundle savedState)
{
    overridePendingTransition(R.anim.anim_slideup, R.anim.anim_hold);
    super.onCreate(savedState);

as someone else mentioned, when you override the animation an activity starts with, you should also override the animation that activity finishes with to match.

@Override public void finish()
{
    super.finish();
    overridePendingTransition(R.anim.anim_hold, R.anim.anim_slidedown);
}

Upvotes: 8

matiash
matiash

Reputation: 55380

A possible trick to get a custom transition for the first activity is to not make it the actual first activity. You can set up a transparent activity as the first one, and having it immediately call the splash screen. Since the first activity is invisible, the perceptible effect is that the splash will enter the screen with the animation you desire.

While transparent activities are not recommended for performance reasons (since they cause both it and the previous activity to be drawn for each frame) this activity will last for a very short time (just enough to be drawn and call the splash one) so it doesn't matter.

For example:

In AndroidManifest.xml:

    <activity
        android:name=".LauncherTransparentActivity"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Translucent" 

        >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name=".SplashActivity" android:label="@string/app_name" />
    <activity android:name=".MainActivity" android:label="@string/app_name" />

Then this code in LauncherTransparentActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_NO_TITLE);

    Handler handler = new Handler();
    handler.postDelayed(new Runnable()
    {
        @Override
        public void run()
        {
            Intent intent = new Intent(LauncherTransparentActivity.this, SplashActivity.class);
            startActivity(intent);
            overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_left);
            finish();
        }

    }, 100);

And finally, in SplashActivity.onCreate(), practically the same code, but with a longer delay and calling the actual MainActivity (more or less the same code as you had).

Two caveats:

  1. Whenever you call overridePendingTransition() to start an activity, be sure to call it again whenever it's finished, with a transition that is logically the opposite. Otherwise it will use the system-default animation when exiting, which is not what you would logically expect (e.g. if it enters from the right, it should probable exit the same way).
  2. Although this is possible (as demonstrated), it may not be a very good idea to override the system default transition for application launch. Users expect certain behavior when launching an app -- basically one that is consistent with launching any other app. Using a custom one instead may be confusing.

Upvotes: 1

Christopher Francisco
Christopher Francisco

Reputation: 16288

call finish() after overridePendingTransition()

Edit: also remove this intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION );. If you dont want an entering animation (from the MainActivity) just pass 0 to the param that's called enterAnim or something like that

Upvotes: 1

Rod_Algonquin
Rod_Algonquin

Reputation: 26198

problem:

intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION );

You are trying disable the animation of your activitys thus giving you no animation

as the documentation is saying:

If set in an Intent passed to Context.startActivity(), this flag will prevent the system from 
applying an activity transition animation to go to the next activity state.

solution:

remove this line

intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION );

edit:

 Intent intent = new Intent(this, MainActivity.class);
    startActivity(intent);
    overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);  

Upvotes: -1

Related Questions