Skip to content

Commit 1a389d9

Browse files
committed
新增 setCanPlayMoveAnimation 方法来设置是否播放窗口移动动画
1 parent 920b9fb commit 1a389d9

3 files changed

Lines changed: 46 additions & 0 deletions

File tree

README-en.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,8 @@ easyWindow.setLayoutInDisplayCutoutMode(int layoutInDisplayCutoutMode);
294294
easyWindow.setPreferMinimalPostProcessing(boolean enabled);
295295
// Set blur radius behind the window (supported on Android 12+)
296296
easyWindow.setBlurBehindRadius(@IntRange(from = 0) int blurBehindRadius);
297+
// Set whether the floating window can play move animations (supported only on Android 14 and above, framework compatible with Android 4.3)
298+
easyWindow.setCanPlayMoveAnimation(boolean enable);
297299

298300
// Set the visibility of the window view
299301
easyWindow.setWindowViewVisibility(int visibility);

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ easyWindow.setLayoutInDisplayCutoutMode(int layoutInDisplayCutoutMode);
300300
easyWindow.setPreferMinimalPostProcessing(boolean enabled);
301301
// 设置悬浮窗背后的高斯模糊半径大小(Android 12 及以上才支持)
302302
easyWindow.setBlurBehindRadius(@IntRange(from = 0) int blurBehindRadius);
303+
// 设置悬浮窗是否可以播放移动动画(Android 14 及以上才支持,框架兼容到 Android 4.3)
304+
easyWindow.setCanPlayMoveAnimation(boolean enable);
303305

304306
// 设置悬浮窗可见性
305307
easyWindow.setWindowViewVisibility(int visibility);

library/src/main/java/com/hjq/window/EasyWindow.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import com.hjq.window.draggable.SpringBackWindowDraggableRule;
4444
import java.lang.ref.Reference;
4545
import java.lang.ref.WeakReference;
46+
import java.lang.reflect.Field;
4647

4748
/**
4849
* author : Android 轮子哥
@@ -681,6 +682,47 @@ public X setBlurBehindRadius(@IntRange(from = 0) int blurBehindRadius) {
681682
return (X) this;
682683
}
683684

685+
/**
686+
* 设置悬浮窗是否可以播放移动动画(Android 14 及以上才支持,框架兼容到 Android 4.3)
687+
*
688+
* @param enable 是否启用移动动画,系统默认为 true,设置为 false 可以让悬浮窗在移动时不播放动画,直接跳转到目标位置
689+
*/
690+
@SuppressWarnings("JavaReflectionMemberAccess")
691+
public X setCanPlayMoveAnimation(boolean enable) {
692+
// 调用此方法可修复在 Android 13 ~ 14 当窗口内容大小改变时窗口位置会跳动的问题
693+
// Github issue 地址:https://github.com/getActivity/EasyWindow/issues/83
694+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
695+
mWindowParams.setCanPlayMoveAnimation(enable);
696+
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
697+
// 查阅 Android 源码,发现 PRIVATE_FLAG_NO_MOVE_ANIMATION 是 从 Android 4.3 开始引入的,所以最低支持到 Android 4.3
698+
// https://cs.android.com/android/platform/superproject/+/android-4.2.2_r1.2b:frameworks/base/core/java/android/view/WindowManager.java
699+
// https://cs.android.com/android/platform/superproject/+/android-4.3.1_r1:frameworks/base/core/java/android/view/WindowManager.java
700+
// 为了全 Android 版本的效果统一,Android 4.3 ~ Android 13 及以下通过私有标志反射实现
701+
try {
702+
Class<WindowManager.LayoutParams> layoutParamsClass = WindowManager.LayoutParams.class;
703+
704+
// 获取 privateFlags 字段
705+
Field privateFlagsField = layoutParamsClass.getField("privateFlags");
706+
// 获取 PRIVATE_FLAG_NO_MOVE_ANIMATION 标志值
707+
Field noMoveAnimationFlagField = layoutParamsClass.getField("PRIVATE_FLAG_NO_MOVE_ANIMATION");
708+
int noMoveAnimationFlag = noMoveAnimationFlagField.getInt(null);
709+
710+
// 将标志位设置到 privateFlags 中
711+
int currentPrivateFlags = privateFlagsField.getInt(mWindowParams);
712+
if (enable) {
713+
currentPrivateFlags &= ~noMoveAnimationFlag;
714+
} else {
715+
currentPrivateFlags |= noMoveAnimationFlag;
716+
}
717+
privateFlagsField.setInt(mWindowParams, currentPrivateFlags);
718+
719+
} catch (Exception ignored) {
720+
// default implementation ignored
721+
}
722+
}
723+
return (X) this;
724+
}
725+
684726
/**
685727
* 重新设置 WindowManager 参数集
686728
*/

0 commit comments

Comments
 (0)