SkillAgentSearch skills...

EasyWindow

Android 悬浮窗框架,好用不解释

Install / Use

/learn @getActivity/EasyWindow

README

English Doc

悬浮窗框架

本框架意在解决一些悬浮窗的需求,如果是普通的 Toast 封装推荐使用 Toaster

集成步骤

  • 如果你的项目 Gradle 配置是在 7.0 以下,需要在 build.gradle 文件中加入
allprojects {
    repositories {
        // JitPack 远程仓库:https://jitpack.io
        maven { url 'https://jitpack.io' }
    }
}
  • 如果你的 Gradle 配置是 7.0 及以上,则需要在 settings.gradle 文件中加入
dependencyResolutionManagement {
    repositories {
        // JitPack 远程仓库:https://jitpack.io
        maven { url 'https://jitpack.io' }
    }
}
  • 配置完远程仓库后,在项目 app 模块下的 build.gradle 文件中加入远程依赖
android {
    // 支持 JDK 1.8
    compileOptions {
        targetCompatibility JavaVersion.VERSION_1_8
        sourceCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    // 悬浮窗框架:https://github.com/getActivity/EasyWindow
    implementation 'com.github.getActivity:EasyWindow:13.5'
}

AndroidX 兼容

  • 如果项目是基于 AndroidX 库,请在项目 gradle.properties 文件中加入以下配置,如果已经加入则可以忽略
# 表示使用 AndroidX
android.useAndroidX = true
# 表示将第三方库迁移到 AndroidX
android.enableJetifier = true
  • 如果项目是基于 Support 库则不需要加入此配置

使用案例

  • Java 用法
// 传入 Activity 对象表示设置成局部的,不需要有悬浮窗权限
// 传入 Application 对象表示设置成全局的,但需要有悬浮窗权限
EasyWindow.with(this)
        .setContentView(R.layout.toast_hint)
        // 设置成可拖拽的
        //.setWindowDraggableRule()
        // 设置显示时长
        .setWindowDuration(1000)
        // 设置动画样式
        //.setWindowAnim(android.R.style.Animation_Translucent)
        // 设置外层是否能被触摸
        //.setOutsideTouchable(false)
        // 设置窗口背景阴影强度
        //.setBackgroundDimAmount(0.5f)
        .setImageDrawableByImageView(android.R.id.icon, R.mipmap.ic_dialog_tip_finish)
        .setTextByTextView(android.R.id.message, "点我消失")
        .setOnClickListenerByView(android.R.id.message, new OnWindowViewClickListener<TextView>() {

            @Override
            public void onClick(@NonNull EasyWindow<?> easyWindow, @NonNull TextView view) {
                easyWindow.cancel();
                // 跳转到某个Activity
                // easyWindow.startActivity(intent);
            }
        })
        .show();
  • Kotlin 用法(二选一)
EasyWindow.with(activity).apply {
    setContentView(R.layout.toast_hint)
    // 设置成可拖拽的
    //setWindowDraggableRule()
    // 设置显示时长
    setWindowDuration(1000)
    // 设置动画样式
    //setWindowAnim(android.R.style.Animation_Translucent)
    // 设置外层是否能被触摸
    //setOutsideTouchable(false)
    // 设置窗口背景阴影强度
    //setBackgroundDimAmount(0.5f)
    setImageDrawableByImageView(android.R.id.icon, R.mipmap.ic_dialog_tip_finish)
    setTextByTextView(android.R.id.message, "点我消失")
    setOnClickListenerByView(android.R.id.message, OnWindowViewClickListener<TextView?> { easyWindow: EasyWindow<*>, view: TextView ->
        easyWindow.cancel()
        // 跳转到某个Activity
        // easyWindow.startActivity(intent)
    })
}.show()
EasyWindow.with(activity)
        .setContentView(R.layout.toast_hint)
        // 设置成可拖拽的
        //.setWindowDraggableRule()
        // 设置显示时长
        .setWindowDuration(1000)
        // 设置动画样式
        //.setWindowAnim(android.R.style.Animation_Translucent)
        // 设置外层是否能被触摸
        //.setOutsideTouchable(false)
        // 设置窗口背景阴影强度
        //.setBackgroundDimAmount(0.5f)
        .setImageDrawableByImageView(android.R.id.icon, R.mipmap.ic_dialog_tip_finish)
        .setTextByTextView(android.R.id.message, "点我消失")
        .setOnClickListenerByView(android.R.id.message, OnWindowViewClickListener<TextView?> { easyWindow: EasyWindow<*>, view: TextView ->
            easyWindow.cancel()
            // 跳转到某个Activity
            // easyWindow.startActivity(intent)
        })
        .show()

没有悬浮窗权限如何全局显示?

  • 没有悬浮窗权限是不能全局显示在其他应用上的,但是全局显示在自己的应用上是可以实现的

  • 但是当前 Activity 创建的悬浮窗只能在当前 Activity 上面显示,如果想在所有的 Activity 都显示需要做特殊处理

  • 我们可以通过 Application 来监听所有 Activity 的生命周期方法,然后在每个 Activity.onCreate 时创建悬浮窗

public final class WindowLifecycleControl implements Application.ActivityLifecycleCallbacks {

    static void with(Application application) {
        application.registerActivityLifecycleCallbacks(new FloatingLifecycle());
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        EasyWindow.with(activity)
                .setContentView(R.layout.xxx)
                .show();
    }

    ......
}

框架的 API 介绍

  • 对象方法
// 显示悬浮窗
easyWindow.show();
// 延迟显示悬浮窗(可在子线程中调用,不怕频繁调用)
easyWindow.delayShow();
easyWindow.delayShow(long delayMillis);
// 将悬浮窗显示在指定 View 的旁边
easyWindow.showAsDropDown(@NonNull View anchorView, int showGravity, int xOff, int yOff);
// 取消显示悬浮窗
easyWindow.cancel();
// 延迟取消显示悬浮窗(可在子线程中调用,不怕频繁调用)
easyWindow.delayCancel();
easyWindow.delayCancel(long delayMillis);
// 取消显示并回收悬浮窗
easyWindow.recycle();
// 延迟回收悬浮窗(可在子线程中调用,不怕频繁调用)
easyWindow.delayRecycle();
easyWindow.delayRecycle(long delayMillis);
// 更新悬浮窗(在更新了悬浮窗参数才需要调用)
easyWindow.update();
// 延迟更新悬浮窗(可在子线程中调用,不怕频繁调用)
easyWindow.delayUpdate();
easyWindow.delayUpdate(long delayMillis);
// 当前悬浮窗是否正在显示
easyWindow.isShowing();

// 设置窗口生命周期回调监听
easyWindow.setOnWindowLifecycleCallback(@Nullable OnWindowLifecycleCallback callback);
// 设置悬浮窗拖拽规则(框架内部提供了两种拖拽规则,MovingWindowDraggableRule 和 SpringBackWindowDraggableRule )
easyWindow.setWindowDraggableRule(@Nullable AbstractWindowDraggableRule draggableRule);
// 设置悬浮窗拖拽规则(可能为空)
easyWindow.getWindowDraggableRule();

// 设置悬浮窗内容布局
easyWindow.setContentView(@LayoutRes int layoutId);
easyWindow.setContentView(@LayoutRes int layoutId, @Nullable OnWindowLayoutInflateListener listener);
easyWindow.setContentView(@NonNull View view);
// 获取内容布局(可能为空)
easyWindow.getContentView();
// 限定悬浮窗显示时长
easyWindow.setWindowDuration(@IntRange(from = 0) int delayMillis);
// 设置悬浮窗 tag
easyWindow.setWindowTag(@Nullable String tag);
// 获取悬浮窗 tag
easyWindow.getWindowTag();
// 设置悬浮窗宽度和高度
easyWindow.setWindowSize(int width, int height);
// 设置悬浮窗大小(按照屏幕百分比)
easyWindow.setWindowSizePercent(@FloatRange(from = 0, to = 1) float widthPercent, @FloatRange(from = 0, to = 1) float heightPercent);

// 设置悬浮窗的位置
easyWindow.setWindowLocation(@Px int x, @Px int y);
easyWindow.setWindowLocation(@GravityFlag int gravity, @Px int x, @Px int y);
// 设置窗口位置(偏移量按照屏幕百分比)
easyWindow.setWindowLocationPercent(@FloatRange(from = 0, to = 1) @Px float horizontalPercent, @FloatRange(from = 0, to = 1) @Px float verticalPercent);
easyWindow.setWindowLocationPercent(@GravityFlag int gravity, @FloatRange(from = 0, to = 1) @Px float horizontalPercent, @FloatRange(from = 0, to = 1) @Px float verticalPercent);

// 设置悬浮窗外层是否可触摸
easyWindow.setOutsideTouchable(boolean touchable);
// 设置悬浮窗背景阴影强度
easyWindow.setBackgroundDimAmount(@FloatRange(from = 0.0, to = 1.0) float amount);

// 添加窗口标记
easyWindow.addWindowFlags(int flags);
// 移除窗口标记
easyWindow.removeWindowFlags(int flags);
// 设置窗口标记
easyWindow.setWindowFlags(int flags);
// 是否存在某个窗口标记
easyWindow.hasWindowFlags(int flags);
// 设置悬浮窗的显示类型
easyWindow.setWindowType(int type);

// 设置悬浮窗动画样式
easyWindow.setWindowAnim(int id);
// 设置悬浮窗软键盘模式
easyWindow.setSoftInputMode(int softInputMode);
// 设置悬浮窗 Token
easyWindow.setWindowToken(@Nullable IBinder token);

// 设置悬浮窗透明度
easyWindow.setWindowAlpha(@FloatRange(from = 0.0, to = 1.0) float alpha);
// 设置容器和窗口小部件之间的垂直边距
easyWindow.setVerticalMargin(float verticalMargin);
// 设置容器和窗口小部件之间的水平边距
easyWindow.setHorizontalMargin(float horizontalMargin);
// 设置位图格式
easyWindow.setBitmapFormat(int format);
// 设置状态栏的可见性
easyWindow.setSystemUiVisibility(int systemUiVisibility);
// 设置垂直权重
easyWindow.setVerticalWeight(float verticalWeight);
// 设置挖孔屏下的显示模式
easyWindow.setLayoutInDisplayCutoutMode(int layoutInDisplayCutoutMode);
// 设置悬浮窗在哪个显示屏上显示
easyWindow.setPreferredDisplayModeId(int preferredDisplayModeId);
// 设置悬浮窗标题
easyWindow.setWindowTitle(@Nullable CharSequence title);
// 设置屏幕的亮度
easyWindow.setScreenBrightness(@FloatRange(from = -1.0, to = 1.0) float screenBrightness);
// 设置键盘背光的亮度
easyWindow.setButtonBrightness(@FloatRange(from = -1.0, to = 1.0) float buttonBrightness);
// 设置悬浮窗的刷新率
easyWindow.setPreferredRefreshRate(float preferredRefreshRate);
// 设置悬浮窗的颜色模式
easyWindow.setColorMode(int colorMode);
// 设置悬浮窗背后的高斯模糊半径大小(Android 12 及以上才支持)
easyWindow.setBlurBehindRadius(@IntRange(from = 0) int blurBehindRadius);
// 设置悬浮窗屏幕方向
easyWindow.setScreenOrientation(int screenOrientation);

// 设置悬浮窗可见性
easyWindow.setWindowViewVisibility(int visibility);
// 获取悬浮窗可见性
easyWindow.getWindowViewVisibility();
// 设置悬浮窗根布局(一般情况下推荐使用 {@link #setContentView} 方法来填充布局)
easyWindow.setRootLayout(@NonNull ViewGroup viewGroup);
// 重新设置 WindowManager 参数集
easyWindow.setWindowParams(@NonNull WindowManager.LayoutParams params);
// 重新设置 WindowManager 对象
easyWindow.setWindowManager(@NonNull WindowManager windowManager);

// 获取当前窗口视图宽度
easyWindow.getWindowViewWidth();
// 获取当前窗口视图高度
easyWindow.getWindowViewHeight();

// 设置可见性状态给 View
easyWindow.setVisibilityByView(@IdRes int viewId, int visibility);
// 设置背景 Drawable 给 View
easyWindow.setBackgroundDrawableByView(@IdRes int viewId, @DrawableRes int drawableId);
easyWindow.setBackgroundDrawableByView(@IdRes int viewId, @Nullable Drawable drawable);
// 设置文本给 TextView
easyWindow.setTextByTextView(@IdRes int viewId, @StringRes int stringId);
easyWindow.setTextByTextView(@IdRes int viewId, @Nullable CharSequence text);
// 设置字体颜色给 TextView
e
View on GitHub
GitHub Stars1.7k
CategoryDevelopment
Updated2d ago
Forks194

Languages

Java

Security Score

95/100

Audited on Mar 28, 2026

No findings