You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android中Activity1至Activity2的Slide退出动画实现求助

实现自定义Activity切换动画:Bloc分向滑出并提前显示目标Activity

看起来你需要的不是系统默认的整页Slide动画,而是让当前Activity内的两个独立区块分别向上下滑出,同时露出下面的目标Activity。这种场景需要结合View级自定义动画透明Activity主题禁用系统过渡动画来实现,下面是具体步骤:

1. 准备动画资源文件

res/anim目录下创建两个动画文件,分别控制BlocA向上滑出、BlocB向下滑出:

slide_up_out.xml(BlocA动画)

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"  <!-- 动画时长,可根据需求调整 -->
    android:fromYDelta="0%"
    android:toYDelta="-100%"  <!-- 向上滑出自身高度 -->
    android:fillAfter="true"/>  <!-- 动画结束后保持最终状态 -->

slide_down_out.xml(BlocB动画)

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:fromYDelta="0%"
    android:toYDelta="100%"  <!-- 向下滑出自身高度 -->
    android:fillAfter="true"/>

2. 设置当前Activity(Activity1)的透明主题

为了让动画过程中能看到下面的Activity2,需要让Activity1的窗口背景透明。在res/values/styles.xml中添加透明主题:

<style name="TransparentActivityTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowAnimationStyle">@null</item>  <!-- 禁用默认窗口动画 -->
</style>

然后在AndroidManifest.xml中为Activity1绑定这个主题:

<activity android:name=".Activity1"
    android:theme="@style/TransparentActivityTheme"/>

3. 编写Activity1的点击与动画逻辑

核心思路是:点击Bloc后,先启动Activity2(禁用系统过渡动画),再让BlocA和BlocB分别执行滑出动画,动画结束后销毁Activity1。

public class Activity1 extends AppCompatActivity {
    private View blocA, blocB;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_1);
        
        blocA = findViewById(R.id.bloc_a);
        blocB = findViewById(R.id.bloc_b);

        // 给两个Bloc设置点击事件
        blocA.setOnClickListener(v -> startCustomTransition());
        blocB.setOnClickListener(v -> startCustomTransition());
    }

    private void startCustomTransition() {
        // 1. 启动Activity2,禁用系统默认的过渡动画
        Intent intent = new Intent(Activity1.this, Activity2.class);
        startActivity(intent);
        overridePendingTransition(0, 0);  // 0表示无动画

        // 2. 加载并启动Bloc的滑出动画
        Animation slideUpAnim = AnimationUtils.loadAnimation(this, R.anim.slide_up_out);
        Animation slideDownAnim = AnimationUtils.loadAnimation(this, R.anim.slide_down_out);

        // 动画结束后的处理:清除动画、隐藏View、销毁当前Activity
        Animation.AnimationListener animListener = new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {}

            @Override
            public void onAnimationEnd(Animation animation) {
                blocA.clearAnimation();
                blocB.clearAnimation();
                blocA.setVisibility(View.GONE);
                blocB.setVisibility(View.GONE);
                // 动画完成后销毁Activity1,避免栈中残留
                finish();
            }

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

        slideUpAnim.setAnimationListener(animListener);
        slideDownAnim.setAnimationListener(animListener);

        blocA.startAnimation(slideUpAnim);
        blocB.startAnimation(slideDownAnim);
    }
}

为什么之前的系统Slide动画没生效?

系统提供的Slide动画(比如android.R.anim.slide_out_up)是针对整个Activity窗口的过渡动画,而你的需求是让窗口内的两个子View分别运动,所以系统动画无法满足这种局部View的自定义滑动效果。通过上面的方案,我们把动画逻辑放在View级别,同时利用透明主题让目标Activity提前显示,完美匹配你的需求。

内容的提问来源于stack exchange,提问作者Mxwan

火山引擎 最新活动