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




