overridePendingTransition() 不起作用

Posted

技术标签:

【中文标题】overridePendingTransition() 不起作用【英文标题】:overridePendingTransition() isn't working 【发布时间】:2014-08-19 03:29:51 【问题描述】:

我正在尝试实现一个快速的 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();
    

【问题讨论】:

"向主要活动的过渡正常" -- 这是否意味着它按预期工作?我虽然是这样,但您的最后评论似乎表明并非如此。 它没有按预期工作,到目前为止,两个动画都没有工作,但是我更关心第二个动画的工作。 代码似乎没问题。标准动画是否正在运行?还是根本没有动画?或者可能是不正确的动画?您能否发布slide_in_right.xmlslide_out_left.xml 文件,并解释您正在尝试的确切动画效果? 哪里/什么是“overridePendingAnimation()”,我还没听说过? @sai 它被称为 overridePendingTransition(他写对了吗),你可以在这里找到它:developer.android.com/reference/android/app/… 【参考方案1】:

我通常从正在启动的活动的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);

【讨论】:

【参考方案2】:

为第一个活动获取自定义转换的一个可能技巧是不使其成为实际第一个活动。您可以将透明活动设置为第一个活动,并让它立即调用启动屏幕。由于第一个 Activity 是不可见的,因此可感知的效果是,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(或多或少与您的代码相同)。

两个警告:

    每当您调用overridePendingTransition() 来启动一个活动时,一定要在它完成后再次调用它,并使用逻辑上相反的转换。否则它会在退出时使用系统默认动画,这不是你在逻辑上所期望的(例如,如果它从右侧进入,它应该可能以相同的方式退出)。 虽然这是可能的(如图所示),但覆盖系统默认转换以启动应用程序可能不是一个好主意。用户在启动应用程序时期望某些行为 - 基本上是与启动任何其他应用程序一致的行为。改用自定义可能会造成混淆。

【讨论】:

【参考方案3】:

据我所知,你只需要放

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

在 MainActivity 内部,而不是 SplashActivity。总是为我工作。

编辑: 实际上,我刚刚看到您正在扩展 Activity。我想你没有使用支持库?然后像

这样的动画
<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>

不会工作,但 ObjectAnimators 会。

【讨论】:

【参考方案4】:

所以如果正确理解你的问题 - 你有两个你想要的动画:

    启动画面加载时的动画

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

第二个有效,但第一个无效。 (现有的答案似乎是针对后者)

问题:

overridePendingTransition() 应该在调用启动活动后立即调用(参见此处:http://developer.android.com/reference/android/app/Activity.html#overridePendingTransition(int, int))。这就是您的第二个动画有效的原因。在您第一次使用它时,您会在系统调用 startActivity 之后很久才使用它。

在我看来,有两种方法可以解决这个问题:

    使用另一个空白活动并启动,然后从该活动滑到您当前的活动

    在您的主要活动中使用另一种动画

我认为第二个对你来说会更简单。谷歌搜索我发现了一些用动画开始活动的例子,例如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_
android:layout_
android:background="#000000"
tools:context="uk.co.airsource.android.common.examples.boundservicetest.app.Splash">

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

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

【讨论】:

查看我的新编辑,完成此操作后,两个动画都不起作用。 看了一下,将其复制到示例应用程序中,效果很好。你也许应该分享你的清单和动画文件 也更新了我的建议并上传了一个工作示例【参考方案5】:

overridePendingTransition()之后调用finish()

编辑:也删除此intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION );。如果您不想要进入动画(来自MainActivity),只需将0 传递给名为enterAnim 或类似的参数

【讨论】:

【参考方案6】:

问题:

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

【讨论】:

这样它会覆盖默认系统动画,如果我删除它仍然不起作用。 @AggieDev 去掉finish 去掉flag,开始activity,见上 这就是我做的所有东西了,finish()是把它从backstack中移除 遗憾的是,删除完成并不能解决问题。

以上是关于overridePendingTransition() 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

窗体切换动画 overridePendingTransition

overridePendingTransition

overridePendingTransition

关于Activity切换动画(overridePendingTransition)的黑色背景问题

overridePendingTransition 用于平滑地滑入和滑出活动

activity启动动画overridePendingTransition()使用