You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Window TransitionManager实现getWindow().setLayout()动画:MATCH_PARENT无动画问题

解决浮动Activity切换全屏无动画的问题

我来帮你梳理下这个问题的核心逻辑和可行的解决方向——其实当你用WRAP_CONTENT或固定数值调用setLayout时,系统能明确感知到窗口尺寸的具体变化差值,所以会触发默认的缩放过渡动画;但MATCH_PARENT是依赖父容器的相对值,系统没法直接获取明确的尺寸变化数据,因此默认不会触发动画。下面给你几个实用的解决思路:


1. 最直接的替代方案:用实际全屏尺寸代替MATCH_PARENT

不用修改TransitionManager,先获取屏幕(或目标父容器)的真实像素尺寸,再用这个固定值调用setLayout,让系统误以为是固定尺寸变化,从而复用默认动画:

// 获取屏幕全屏的实际像素尺寸
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int fullScreenWidth = displayMetrics.widthPixels;
int fullScreenHeight = displayMetrics.heightPixels;

// 切换全屏时使用实际尺寸,而非MATCH_PARENT
getWindow().setLayout(fullScreenWidth, fullScreenHeight);

这个方案的优点是简单高效,几乎不需要额外代码;唯一需要注意的是,如果屏幕旋转或父容器尺寸变化,需要重新获取最新尺寸,但大部分浮动窗口场景下完全够用。


2. 自定义TransitionManager适配MATCH_PARENT

如果一定要坚持使用MATCH_PARENT,可以自定义Transition来处理相对尺寸的变化逻辑,核心是手动计算尺寸差值并创建动画:

步骤1:自定义Transition类

public class FullscreenTransition extends Transition {
    private static final String KEY_WINDOW_RECT = "windowRect";

    @Override
    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
        if (startValues == null || endValues == null) return null;

        // 获取起始和目标窗口尺寸
        Rect startRect = (Rect) startValues.values.get(KEY_WINDOW_RECT);
        Rect endRect = (Rect) endValues.values.get(KEY_WINDOW_RECT);

        // 创建缩放动画(可根据需求添加位移、透明度等效果)
        View decorView = sceneRoot;
        ObjectAnimator widthAnim = ObjectAnimator.ofInt(decorView, "width", startRect.width(), endRect.width());
        ObjectAnimator heightAnim = ObjectAnimator.ofInt(decorView, "height", startRect.height(), endRect.height());
        
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(widthAnim, heightAnim);
        animatorSet.setDuration(300); // 自定义动画时长
        return animatorSet;
    }

    @Override
    public void captureStartValues(TransitionValues transitionValues) {
        super.captureStartValues(transitionValues);
        // 捕获窗口当前的起始尺寸
        View view = transitionValues.view;
        transitionValues.values.put(KEY_WINDOW_RECT, new Rect(0, 0, view.getWidth(), view.getHeight()));
    }

    @Override
    public void captureEndValues(TransitionValues transitionValues) {
        super.captureEndValues(transitionValues);
        // 捕获全屏状态的目标尺寸
        WindowManager windowManager = (WindowManager) transitionValues.view.getContext().getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(metrics);
        transitionValues.values.put(KEY_WINDOW_RECT, new Rect(0, 0, metrics.widthPixels, metrics.heightPixels));
    }
}

步骤2:绑定TransitionManager到窗口

// 初始化自定义TransitionManager
TransitionManager transitionManager = new TransitionManager();
Scene fullscreenScene = new Scene(getWindow().getDecorView());
transitionManager.setTransitionToScene(fullscreenScene, new FullscreenTransition());
getWindow().setTransitionManager(transitionManager);

// 切换全屏时触发动画
TransitionManager.beginDelayedTransition(getWindow().getDecorView());
getWindow().setLayout(MATCH_PARENT, MATCH_PARENT);

注意:这里的动画目标是Window的DecorView,也可以直接操作Window的LayoutParams来更精准地控制尺寸变化。


3. 用窗口动画风格替代TransitionManager

你也可以通过自定义主题动画来实现过渡效果,绕开TransitionManager的限制:

步骤1:定义动画资源

在res/anim/scale_in.xml中写全屏缩放进入动画:

<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:fromXScale="0.8"
    android:fromYScale="0.8"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="1.0"
    android:toYScale="1.0"/>

步骤2:在主题中配置窗口动画

<style name="FloatingWindowAnimStyle" parent="@android:style/Animation">
    <item name="android:windowEnterAnimation">@anim/scale_in</item>
</style>

步骤3:切换状态时触发动画

// 设置窗口动画
getWindow().setWindowAnimations(R.style.FloatingWindowAnimStyle);
// 切换全屏
getWindow().setLayout(MATCH_PARENT, MATCH_PARENT);

这种方式更适合简单的过渡场景,缺点是动画逻辑和布局切换的耦合度较高。


内容的提问来源于stack exchange,提问作者Michał Klimczak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:33:46