设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间01 现在时间01 缓存数据 当你走完一段之后回头看,你会发现,那些真正能被记得的事真的是没有多少,真正无法忘记的人屈指可数,真正有趣的日子不过是那么一些,而真正需要害怕的也是寥寥无几。

当你走完一段之后回头看,你会发现,那些真正能被记得的事真的是没有多少,真正无法忘记的人屈指可数,真正有趣的日子不过是那么一些,而真正需要害怕的也是寥寥无几。

查看: 639|回复: 2

Android Studio实现自定义全局悬浮按钮的示例代码

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:233
  • 打卡月天数:0
  • 打卡总奖励:3511
  • 最近打卡:2025-10-19 09:18:15
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
382
主题
360
精华
0
金钱
4666
积分
809
注册时间
2023-1-3
最后登录
2025-10-19

发表于 2025-9-8 11:12:38 | 显示全部楼层 |阅读模式
一、基础实现方案


1. 使用 WindowManager 实现全局悬浮窗

这是最灵活的实现方式,可以在任何界面显示悬浮按钮:
  1. public class FloatingButtonService extends Service {
  2.     private WindowManager windowManager;
  3.     private View floatingButton;

  4.     @Override
  5.     public IBinder onBind(Intent intent) {
  6.         return null;
  7.     }

  8.     @Override
  9.     public void onCreate() {
  10.         super.onCreate();
  11.         
  12.         // 创建悬浮按钮视图
  13.         floatingButton = LayoutInflater.from(this).inflate(R.layout.floating_button, null);
  14.         
  15.         // 设置按钮点击事件
  16.         floatingButton.findViewById(R.id.float_button).setOnClickListener(v -> {
  17.             // 处理点击事件
  18.             Toast.makeText(this, "悬浮按钮被点击", Toast.LENGTH_SHORT).show();
  19.         });

  20.         // 设置窗口参数
  21.         WindowManager.LayoutParams params = new WindowManager.LayoutParams(
  22.             WindowManager.LayoutParams.WRAP_CONTENT,
  23.             WindowManager.LayoutParams.WRAP_CONTENT,
  24.             Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
  25.                 WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
  26.                 WindowManager.LayoutParams.TYPE_PHONE,
  27.             WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
  28.             PixelFormat.TRANSLUCENT);
  29.         
  30.         // 设置初始位置
  31.         params.gravity = Gravity.TOP | Gravity.START;
  32.         params.x = 0;
  33.         params.y = 100;
  34.         
  35.         // 获取WindowManager并添加视图
  36.         windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
  37.         windowManager.addView(floatingButton, params);
  38.         
  39.         // 添加拖拽功能
  40.         addDragFeature();
  41.     }

  42.     private void addDragFeature() {
  43.         floatingButton.setOnTouchListener(new View.OnTouchListener() {
  44.             private int initialX;
  45.             private int initialY;
  46.             private float initialTouchX;
  47.             private float initialTouchY;

  48.             @Override
  49.             public boolean onTouch(View v, MotionEvent event) {
  50.                 switch (event.getAction()) {
  51.                     case MotionEvent.ACTION_DOWN:
  52.                         initialX = params.x;
  53.                         initialY = params.y;
  54.                         initialTouchX = event.getRawX();
  55.                         initialTouchY = event.getRawY();
  56.                         return true;
  57.                     case MotionEvent.ACTION_MOVE:
  58.                         params.x = initialX + (int) (event.getRawX() - initialTouchX);
  59.                         params.y = initialY + (int) (event.getRawY() - initialTouchY);
  60.                         windowManager.updateViewLayout(floatingButton, params);
  61.                         return true;
  62.                 }
  63.                 return false;
  64.             }
  65.         });
  66.     }

  67.     @Override
  68.     public void onDestroy() {
  69.         super.onDestroy();
  70.         if (floatingButton != null) {
  71.             windowManager.removeView(floatingButton);
  72.         }
  73.     }
  74. }
复制代码
2. 布局文件 (res/layout/floating_button.xml)
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="wrap_content"
  4.     android:layout_height="wrap_content">

  5.     <ImageButton
  6.         android:id="@+id/float_button"
  7.         android:layout_width="56dp"
  8.         android:layout_height="56dp"
  9.         android:background="@drawable/circle_background"
  10.         android:src="@drawable/ic_float_button"
  11.         android:elevation="8dp"
  12.         android:layout_margin="16dp" />

  13. </FrameLayout>
复制代码
3. 圆形背景 (res/drawable/circle_background.xml)
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:shape="oval">
  4.     <solid android:color="@color/colorPrimary" />
  5. </shape>
复制代码
4. 启动服务
  1. // 在需要显示悬浮按钮的地方启动服务
  2. startService(new Intent(context, FloatingButtonService.class));

  3. // 停止服务
  4. stopService(new Intent(context, FloatingButtonService.class));
复制代码
二、权限处理


1. AndroidManifest.xml 中添加权限
  1. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
复制代码
2. 检查并请求权限
  1. // 检查悬浮窗权限
  2. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  3.     if (!Settings.canDrawOverlays(this)) {
  4.         Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
  5.                 Uri.parse("package:" + getPackageName()));
  6.         startActivityForResult(intent, OVERLAY_PERMISSION_REQ);
  7.     } else {
  8.         // 已经有权限,启动服务
  9.         startService(new Intent(this, FloatingButtonService.class));
  10.     }
  11. } else {
  12.     // 6.0以下直接启动
  13.     startService(new Intent(this, FloatingButtonService.class));
  14. }
复制代码
三、高级功能扩展


1. 添加动画效果
  1. // 在按钮点击时添加动画
  2. floatingButton.setOnClickListener(v -> {
  3.     // 缩放动画
  4.     ObjectAnimator scaleX = ObjectAnimator.ofFloat(v, "scaleX", 1f, 0.8f, 1f);
  5.     ObjectAnimator scaleY = ObjectAnimator.ofFloat(v, "scaleY", 1f, 0.8f, 1f);
  6.    
  7.     AnimatorSet animatorSet = new AnimatorSet();
  8.     animatorSet.playTogether(scaleX, scaleY);
  9.     animatorSet.setDuration(200);
  10.     animatorSet.start();
  11.    
  12.     // 执行点击操作
  13.     performButtonAction();
  14. });
复制代码
2. 自动吸附边缘
  1. private void autoAttachToEdge() {
  2.     int screenWidth = getResources().getDisplayMetrics().widthPixels;
  3.     int buttonWidth = floatingButton.getWidth();
  4.    
  5.     if (params.x < screenWidth / 2 - buttonWidth / 2) {
  6.         // 吸附到左边
  7.         params.x = 0;
  8.     } else {
  9.         // 吸附到右边
  10.         params.x = screenWidth - buttonWidth;
  11.     }
  12.    
  13.     windowManager.updateViewLayout(floatingButton, params);
  14. }
复制代码
3. 显示/隐藏动画
  1. public void hideButton() {
  2.     floatingButton.animate()
  3.         .translationY(floatingButton.getHeight())
  4.         .setDuration(300)
  5.         .start();
  6. }

  7. public void showButton() {
  8.     floatingButton.animate()
  9.         .translationY(0)
  10.         .setDuration(300)
  11.         .start();
  12. }
复制代码
四、优化建议


  • 性能优化

    • 使用轻量级的视图层级
    • 避免频繁调用
      1. updateViewLayout
      复制代码
    • 使用硬件加速

  • 内存管理

    • 在不需要时及时移除悬浮窗
    • 在低内存时自动隐藏

  • 用户体验

    • 添加适当的触摸反馈
    • 考虑屏幕旋转时的位置调整
    • 提供设置选项让用户自定义位置和行为

  • 兼容性处理

    • 处理不同 Android 版本的权限差异
    • 适配各种屏幕尺寸和密度
    • 考虑全面屏和刘海屏的适配


五、替代方案


1. 使用 CoordinatorLayout + FloatingActionButton

如果只需要在应用内显示悬浮按钮,可以使用 Material Design 组件:
  1. <androidx.coordinatorlayout.widget.CoordinatorLayout
  2.     android:layout_width="match_parent"
  3.     android:layout_height="match_parent">

  4.     <!-- 其他内容 -->

  5.     <com.google.android.material.floatingactionbutton.FloatingActionButton
  6.         android:id="@+id/fab"
  7.         android:layout_width="wrap_content"
  8.         android:layout_height="wrap_content"
  9.         android:layout_gravity="bottom|end"
  10.         android:layout_margin="16dp"
  11.         android:src="@drawable/ic_add" />

  12. </androidx.coordinatorlayout.widget.CoordinatorLayout>
复制代码
2. 使用第三方库

一些流行的悬浮按钮库:

  • FloatingView
  • DraggablePanel
  • FloatWindow

六、常见问题解决


  • 权限问题

    • 确保已正确请求
      1. SYSTEM_ALERT_WINDOW
      复制代码
      权限
    • 在 Android 6.0+ 上需要动态请求权限
    • 某些厂商 ROM 可能需要额外的白名单设置

  • 位置不正确

    • 检查
      1. WindowManager.LayoutParams
      复制代码
      的 gravity 设置
    • 考虑状态栏和导航栏的高度
    • 在屏幕旋转时更新位置

  • 点击穿透

    • 设置
      1. FLAG_NOT_FOCUSABLE
      复制代码
      可能导致点击事件穿透
    • 可以通过在
      1. onTouch
      复制代码
      中返回
      1. true
      复制代码
      来拦截事件

  • 内存泄漏

    • 确保在服务销毁时移除视图
    • 避免在视图中持有 Activity 引用

以上就是Android Studio实现自定义全局悬浮按钮的示例代码的详细内容,更多关于Android Studio悬浮按钮的资料请关注晓枫资讯其它相关文章!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
19
积分
18
注册时间
2022-12-24
最后登录
2022-12-24

发表于 2025-11-16 13:06:44 | 显示全部楼层
感谢楼主分享。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
15
积分
10
注册时间
2022-12-25
最后登录
2022-12-25

发表于 昨天 23:33 | 显示全部楼层
顶顶更健康!!!
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼
3楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表