uniapp如何实现系统级悬浮窗功能

在uniapp中如何实现类似微信悬浮窗的系统级悬浮窗功能?需要支持跨页面显示,且能拖动到屏幕任意位置。目前测试发现uni.createLivePusherContext创建的悬浮窗只能在当前页面显示,退出页面后就会消失。请问有没有完整的解决方案或插件推荐?最好能兼容Android和iOS平台。

2 回复

uniapp本身不支持系统级悬浮窗。可通过原生插件实现,比如用Android的WindowManager或iOS的UIWindow。需分别开发原生插件,在uniapp中调用。注意权限问题,如Android的SYSTEM_ALERT_WINDOW权限。


在 UniApp 中,系统级悬浮窗功能通常需要依赖原生开发实现,因为 UniApp 本身是跨端框架,无法直接操作系统级权限或组件。以下是实现方案和步骤:

实现思路

  1. 使用 UniApp 的 Native.js:通过调用原生 Android/iOS API 实现(仅 App 端支持)。
  2. 开发原生插件:封装原生代码为 UniApp 插件,供 JavaScript 调用。
  3. 注意事项:系统悬浮窗需用户手动授权,且不同厂商(如小米、华为)可能有兼容性问题。

示例代码(Android 端 via Native.js)

以下以 Android 为例,演示如何创建悬浮窗(需在 manifest.json 中申请 SYSTEM_ALERT_WINDOW 权限):

// 在 UniApp 的 Vue 页面中
export default {
  methods: {
    createFloatingWindow() {
      // 判断平台
      if (uni.getSystemInfoSync().platform === 'android') {
        const Context = plus.android.importClass('android.content.Context');
        const WindowManager = plus.android.importClass('android.view.WindowManager');
        const LayoutParams = plus.android.importClass('android.view.WindowManager.LayoutParams');
        const Button = plus.android.importClass('android.widget.Button');
        const View = plus.android.importClass('android.view.View');

        // 获取系统服务
        const main = plus.android.runtimeMainActivity();
        const wm = main.getSystemService(Context.WINDOW_SERVICE);

        // 创建布局参数
        const params = new LayoutParams(
          LayoutParams.WRAP_CONTENT,
          LayoutParams.WRAP_CONTENT,
          LayoutParams.TYPE_APPLICATION_OVERLAY, // 系统悬浮窗类型(API 26+)
          LayoutParams.FLAG_NOT_FOCUSABLE,
          PixelFormat.TRANSLUCENT
        );

        // 创建按钮(示例视图)
        const button = new Button(main);
        button.setText("悬浮按钮");
        button.setOnClickListener(new View.OnClickListener({
          onClick: function() {
            uni.showToast({ title: '点击悬浮窗', icon: 'none' });
          }
        }));

        // 添加悬浮窗
        wm.addView(button, params);
      } else {
        uni.showToast({ title: '仅支持 Android', icon: 'none' });
      }
    }
  }
}

关键步骤

  1. 权限申请
    • manifest.jsonApp权限配置 中勾选 “悬浮窗权限”
    • 对于 Android 6.0+,需动态申请权限:
      // 示例动态申请代码
      plus.android.requestPermissions(['android.permission.SYSTEM_ALERT_WINDOW'], function() {
        console.log('授权成功');
      }, function() {
        console.log('授权失败');
      });
      
  2. 兼容性处理
    • 部分 Android 厂商(如小米、OPPO)需引导用户手动开启悬浮窗权限。
    • iOS 限制严格,不支持系统级悬浮窗,仅能通过 cover-view 在应用内模拟。

替代方案(应用内悬浮)

如果无需系统级悬浮,可使用 cover-view 在应用内模拟悬浮按钮:

<template>
  <view>
    <cover-view class="float-btn" @click="handleClick">悬浮按钮</cover-view>
  </view>
</template>

<style>
.float-btn {
  position: fixed;
  bottom: 100px;
  right: 20px;
  width: 80px;
  height: 80px;
  background: #007AFF;
  color: white;
  border-radius: 50%;
  text-align: center;
  line-height: 80px;
}
</style>

总结

  • 系统级悬浮窗需原生开发支持,推荐通过封装原生插件实现。
  • 注意权限管理和厂商兼容性,必要时引导用户手动授权。
  • iOS 无法实现系统悬浮窗,需考虑应用内替代方案。
回到顶部