overridePendingTransition()不起作用

时间:2014-06-27 22:31:08

标签: android animation android-activity fragment

我正在尝试实现从右向左滑动的快速SplashActivity,然后在MainActivity向右滑动时向左滑动。目前,动画XML已经到位,但它不起作用,只是出现闪屏,然后转换到主要活动也不起作用。这是SplashActivity,它是应用程序的开始活动。

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

由于某种原因这不起作用,我做错了什么?

编辑:这是我的新goToMainActivity()方法,但两个动画仍然没有工作。在这一点上,我并不关心第一个动画工作,我只想让第二个动画工作。

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

6 个答案:

答案 0 :(得分:4)

我通常会从正在启动的活动的onCreate()函数中覆盖动画,这看起来效果很好。呼叫者应该startActivity()正常;不要使用overridePendingTransition()FLAG_ACTIVITY_NO_ANIMATION或其他任何内容。

复制&从实际部署的代码中粘贴:

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

正如其他人提到的那样,当你覆盖一个活动开始的动画时,你也应该覆盖活动完成的动画以匹配。

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

答案 1 :(得分:1)

因此,如果正确理解您的问题 - 您需要两个动画:

  1. 加载时启动画面的动画

  2. 从初始屏幕到主要活动的动画

  3. 秒数正在起作用,但第一个不是。 (现有的答案似乎是针对后者)

    问题:

    在调用启动活动后,

    overridePendingTransition()应该被立即调用(参见这里:http://developer.android.com/reference/android/app/Activity.html#overridePendingTransition(int,int))。这就是你的第二个动画工作的原因。在你的第一次使用它之后很久就调用了startActivity,这是由系统完成的。

    我认为有两种方法可以解决这个问题:

    1. 使用其他空白活动并启动,然后从该活动滑动到当前活动

    2. 在主要活动中使用其他类型的动画

    3. 我认为第二种方法对你来说更简单。谷歌搜索我发现一些动画启动活动的例子,例如Android: start the app with animation

      所以我们可以调整它以使用翻译动画(http://developer.android.com/reference/android/view/animation/TranslateAnimation.html)(现在已经过测试 - 而不是动画在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);
      }
      

      其中splashRoot是具有所需背景颜色的父视图内的视图:

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

      也从这里改编:Translate animation to correct position in Android

      我认为,无论你的应用程序何时开始,你都会从系统中得到一些动画 - 系统有一些动画可以切换到我不知道的任何覆盖的不同任务。

      更新:我把最后一句话拿回来。您可以使用自己的应用主题来覆盖动画,请参阅此处:How to override the enter activity animation if it is stated by launcher但请仔细阅读“hackbod的警告”

      编辑:我测试了我的建议,并在上面添加了一些内容。我还在这里上传了完整的工作示例活动(我实际上为我现有的示例应用添加了一个启动画面):https://github.com/samskiter/BoundServiceTest/tree/splash

答案 2 :(得分:1)

为第一个活动获取自定义转换的一个可能技巧是不将其作为实际第一个活动。您可以将透明活动设置为第一个,并让它立即调用启动屏幕。由于第一个活动是不可见的,因此可感知的效果是飞溅将以您想要的动画进入屏幕。

虽然出于性能原因不建议使用透明活动(因为它们会导致每个帧都绘制它和之前的活动),但此活动将持续很短的时间(刚好足以绘制并调用splash)所以没关系。

例如:

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" />

然后这段代码在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);

最后,在SplashActivity.onCreate()中,几乎相同的代码,但延迟较长并调用实际 MainActivity(或多或少与您的代码相同)

两个警告:

  1. 每当你打电话给overridePendingTransition()开始一项活动时,请务必在完成时再次调用它,并且转换在逻辑上相反。否则它将在退出时使用系统默认动画,这不是您在逻辑上期望的(例如,如果它从右侧进入,它可能以相同的方式退出)。
  2. 虽然这是可能的(如图所示),但覆盖应用程序启动的系统默认转换可能不是一个好主意。用户期望启动应用时的某些行为 - 基本上与启动任何其他应用一致。使用自定义的可能会令人困惑。

答案 3 :(得分:0)

finish()

之后致电overridePendingTransition()

修改也会删除此intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION );。如果您不想要输入动画(来自MainActivity),只需将0传递给名为enterAnim的param或类似的

答案 4 :(得分:0)

答案 5 :(得分:-1)

<强>问题:

intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION );

您正在尝试禁用活动的动画,因此不会给您动画

正如documentation所说:

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.

<强>溶液

删除此行

intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION );

编辑:

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