iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Android应用内悬浮窗的实现方案示例
  • 192
分享到

Android应用内悬浮窗的实现方案示例

android 2023-05-30 22:05:17 192人浏览 八月长安
摘要

1、悬浮窗的基本介绍悬浮窗,大家应该也不陌生,凌驾于应用之上的一个小弹窗,实现上很简单,就是添加一个系统级别的窗口,Android中通过WindowManagerService( WMS)来管理所有的窗口,对于WMS来说,管你是Activi

1、悬浮窗的基本介绍

悬浮窗,大家应该也不陌生,凌驾于应用之上的一个小弹窗,实现上很简单,就是添加一个系统级别的窗口,Android中通过WindowManagerService( WMS)来管理所有的窗口,对于WMS来说,管你是Activity、Toast、Dialog,都不过是通过WindowManagerGlobal.addView()添加的一个个View。

Android中的窗口分为三个级别:

1 应用窗口,比如Activity的窗口;

2 子窗口,依赖于父窗口,比如PopupWindow;

3 系统窗口,比如状态栏、Toast,目标悬浮窗就是系统窗口.

2、根据产品需求进行设计

先了解一下大概的产品需求:

悬浮窗需要跨越整个应用
2、需要与悬浮窗进行交互
3、悬浮窗得移动
4、点击跳转特定的页面
5、消息提示的拖拽小红点

需求很简单,但是如果估算没错,不下一周产品经理会添加新的需求,所以为了更好的后续扩展,需要进行合理的设计,主要分为以下几点:

悬浮窗自定义一个FrameLayout布局FloatLayout,里面进行拖动及点击响应处理;
2、FloatMonkService,是一个服务,开启服务的时候创建悬浮窗;
3、FloatCallBack,交互接口,在FloatMonkService里面实现接口,用于交互;
4、FloatWindowManager,悬浮窗的管理,因为后续悬浮窗布局可能有好几个,可以在这里面进行切换;
5、HomeWatcherReceiver,广播接收者,因为在应用内展示,需要监听用户在点击Home键和切换键的时候隐藏悬浮窗,需要FloatMonkService里头动态注册;
6、FloatActionController,其实就是代理,其它模块需要通过它来和悬浮窗进行交互,真正干活的是实现FloatCallBack接口的FloatMonkService;
7、FloatPermissionManager,需要适配各个傻逼机型的权限,庆幸网上已有大佬分享,只需要单独对7.0系统进行一些适配就行,悬浮窗权限适配;
8、拖拽控件DraggableFlagView,直接拿来在悬浮窗上出现很奇怪的问题,所以需要改造一下下才能达到图中效果。

3、具体实现

float_littlemonk_layout.xml

<FrameLayout xmlns:android="Http://schemas.android.com/apk/res/android"  xmlns:dfv="http://schemas.android.com/apk/res-auto"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:gravity="center"  android:orientation="vertical">  <RelativeLayout    android:id="@+id/monk_relative_root"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <ImageView      android:id="@+id/float_id"      android:layout_width="70dp"      android:layout_height="80dp"      android:layout_gravity="center_vertical|end"      android:scaleType="center"      android:src="@drawable/little_monk" />  </RelativeLayout>  <FrameLayout    android:layout_width="match_parent"    android:layout_height="match_parent">    <floatwindow.xishuang.float_lib.view.DraggableFlagView      android:id="@+id/main_dfv"      android:layout_width="17dp"      android:layout_height="17dp"      android:layout_gravity="end"      dfv:color1="#FF3B30" />  </FrameLayout></FrameLayout>

简单的布局,就是一张图片+右上角放一个自定义的小红点。

FloatLayout.java

@Override  public boolean onTouchEvent(MotionEvent event) {    // 获取相对屏幕的坐标,即以屏幕左上角为原点    int x = (int) event.getRawX();    int y = (int) event.getRawY();    //下面的这些事件,跟图标的移动无关,为了区分开拖动和点击事件    int action = event.getAction();    switch (action) {      case MotionEvent.ACTION_DOWN:        startTime = System.currentTimeMillis();        mTouchStartX = event.getX();        mTouchStartY = event.getY();        break;      case MotionEvent.ACTION_MOVE:        //图标移动的逻辑在这里        float mMoveStartX = event.getX();        float mMoveStartY = event.getY();        // 如果移动量大于3才移动        if (Math.abs(mTouchStartX - mMoveStartX) > 3            && Math.abs(mTouchStartY - mMoveStartY) > 3) {          // 更新浮动窗口位置参数          mWmParams.x = (int) (x - mTouchStartX);          mWmParams.y = (int) (y - mTouchStartY);          mWindowManager.updateViewLayout(this, mWmParams);          return false;        }        break;      case MotionEvent.ACTION_UP:        endTime = System.currentTimeMillis();        //当从点击到弹起小于半秒的时候,则判断为点击,如果超过则不响应点击事件        if ((endTime - startTime) > 0.1 * 1000L) {          isclick = false;        } else {          isclick = true;        }        break;    }    //响应点击事件    if (isclick) {      Toast.makeText(mContext, "我是大傻叼", Toast.LENGTH_SHORT).show();    }    return true;  }

为了把悬浮窗的view操作抽离出来,自定义了这个布局,主要进行两部分功能,悬浮窗的移动和点击处理,重点是通过mWindowManager.updateViewLayout(this, mWmParams)来进行悬浮窗的位置移动,我这个Demo里面只是简单的通过时间来判断点击事件,有必要的话点击事件需要添加特定View范围判断来响应点击。

// 如果移动量大于3才移动if (Math.abs(mTouchStartX - mMoveStartX) > 3 && Math.abs(mTouchStartY - mMoveStartY) > 3)

这个判断是为了避免点击悬浮窗不在重心位置会出现移动的现象。

FloatMonkService.java

public class FloatMonkService extends Service implements FloatCallBack {    private HomeWatcherReceiver mHomeKeyReceiver;  @Override  public void onCreate() {    super.onCreate();    FloatActionController.getInstance().reGISterCallLittleMonk(this);    //注册广播接收者    mHomeKeyReceiver = new HomeWatcherReceiver();    final IntentFilter homeFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);    registerReceiver(mHomeKeyReceiver, homeFilter);    //初始化悬浮窗UI    initWindowData();  }  @Override  public IBinder onBind(Intent intent) {    return null;  }    private void initWindowData() {    FloatWindowManager.createFloatWindow(this);  }  @Override  public void onDestroy() {    super.onDestroy();    //移除悬浮窗    FloatWindowManager.removeFloatWindowManager();    //注销广播接收者    if (null != mHomeKeyReceiver) {      unregisterReceiver(mHomeKeyReceiver);    }  }  /////////////////////////////////////////////////////////实现接口////////////////////////////////////////////////////  @Override  public void guideUser(int type) {    FloatWindowManager.updataRedAndDialog(this);  }    @Override  public void hide() {    FloatWindowManager.hide();  }    @Override  public void show() {    FloatWindowManager.show();  }    @Override  public void addObtainNumer() {    FloatWindowManager.addObtainNumer(this);    guideUser(4);  }    @Override  public void setObtainNumber(int number) {    FloatWindowManager.setObtainNumber(this, number);  }}

服务开启的时候通过FloatWindowManager.createFloatWindow(this)来创建悬浮窗,实现FloatCallBack 实现需要交互的接口。下面看一下创建悬浮窗的真正操作是怎样的。

FloatWindowManager.java

  public static void createFloatWindow(Context context) {    wmParams = new WindowManager.LayoutParams();    WindowManager windowManager = getWindowManager(context);    mFloatLayout = new FloatLayout(context);    if (Build.VERSION.SDK_INT >= 24) {       wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;    } else {       String packname = context.getPackageName();      PackageManager pm = context.getPackageManager();      boolean permission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.SYSTEM_ALERT_WINDOW", packname));      if (permission) {        wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;      } else {        wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;      }    }    //设置图片格式,效果为背景透明    wmParams.fORMat = PixelFormat.RGBA_8888;    //设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作)    wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;    //调整悬浮窗显示的停靠位置为左侧置顶    wmParams.gravity = Gravity.START | Gravity.TOP;    DisplayMetrics dm = new DisplayMetrics();    //取得窗口属性    mWindowManager.getDefaultDisplay().getMetrics(dm);    //窗口的宽度    int screenWidth = dm.widthPixels;    //窗口高度    int screenHeight = dm.heightPixels;    //以屏幕左上角为原点,设置x、y初始值,相对于gravity    wmParams.x = screenWidth;    wmParams.y = screenHeight;    //设置悬浮窗口长宽数据    wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;    wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;    mFloatLayout.setParams(wmParams);    windowManager.addView(mFloatLayout, wmParams);    mHasshown = true;    //是否展示小红点展示    checkRedDot(context);  }  private static WindowManager getWindowManager(Context context) {    if (mWindowManager == null) {      mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);    }    return mWindowManager;  }

核心代码其实就是mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE),其中的context不能是Activity的,一开始就说了,Activity会返回它专享的WindowManager,而Activity的窗口级别是属于应用层的。进行一些初始化操作之后 windowManager.addView(mFloatLayout, wmParams)把布局添加进去就ok了。

 if (Build.VERSION.SDK_INT >= 24) {       wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;    } else {       String packname = context.getPackageName();      PackageManager pm = context.getPackageManager();      boolean permission = (PackageManager.PERMISSION_GRANTED == pm.checkPermission("android.permission.SYSTEM_ALERT_WINDOW", packname));      if (permission) {        wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;      } else {        wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;      }    }

说一下这段代码的意义,当WindowManager.LayoutParams.type设置为WindowManager.LayoutParams.TYPE_TOAST的时候,是可以跳过权限申请的,但是为毛又单独适配各个机型呢,因为我们有小米Android系统,魅族Android系统,还有华为等等Android系统,特别是产品经理的魅族,一些特殊机型上是没有效果的,所以为了更保险,得再加一份权限申请,还有一点得提一下,那就是7.0上WindowManager.LayoutParams.TYPE_TOAST,悬浮窗只能持续一秒的时间,所以7.0不设这个type,谷歌爸爸最叼,7.0以上老老实实申请权限。

FloatActionController.java

public class FloatActionController {  private FloatActionController() {  }  public static FloatActionController getInstance() {    return LittleMonkProviderHolder.sInstance;  }  // 静态内部类  private static class LittleMonkProviderHolder {    private static final FloatActionController sInstance = new FloatActionController();  }  private FloatCallBack mCallLittleMonk;    public void startMonkServer(Context context) {    Intent intent = new Intent(context, FloatMonkService.class);    context.startService(intent);  }    public void stopMonkServer(Context context) {    Intent intent = new Intent(context, FloatMonkService.class);    context.stopService(intent);  }    public void registerCallLittleMonk(FloatCallBack callLittleMonk) {    mCallLittleMonk = callLittleMonk;  }    public void show() {    if (mCallLittleMonk == null) return;    mCallLittleMonk.show();  }    public void hide() {    if (mCallLittleMonk == null) return;    mCallLittleMonk.hide();  }}

这就是暴露出来的接口,按需添加,效果大概是这样的。

大概效果如下:

Android应用内悬浮窗的实现方案示例

Demo:代码地址感兴趣可以看看完整的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: Android应用内悬浮窗的实现方案示例

本文链接: https://www.lsjlt.com/news/221879.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android应用内悬浮窗的实现方案示例
    1、悬浮窗的基本介绍悬浮窗,大家应该也不陌生,凌驾于应用之上的一个小弹窗,实现上很简单,就是添加一个系统级别的窗口,Android中通过WindowManagerService( WMS)来管理所有的窗口,对于WMS来说,管你是Activi...
    99+
    2023-05-30
    android
  • Android应用内悬浮窗Activity如何实现
    这篇文章主要介绍Android应用内悬浮窗Activity如何实现,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!缩放方法缩放activity需要使用WindowManager.LayoutParams,控制windo...
    99+
    2023-06-22
  • Android应用内悬浮窗Activity的简单实现
    目录前言缩放方法悬浮样式点击穿透空白移动悬浮窗例子的完整代码styles.xmllayoutactivity运行效果小结前言 悬浮窗是一种比较常见的需求。例如把视频通话界面缩小成一个...
    99+
    2024-04-02
  • Android实现悬浮窗的简单方法实例
    目录1. 前言2.原理3.具体实现3.1浮窗布局3.2 悬浮窗的实现1. 使用服务Service2. 获取WindowManager并设置LayoutParams3. 创建View并...
    99+
    2024-04-02
  • Android无障碍全局悬浮窗实现示例
    目录无障碍添加 UI配置分析TypeFlagLayoutInDisplayCutoutModeAndroid 无障碍的全局悬浮窗可以在屏幕上添加 UI 供用户进行快捷操作,可以展示在...
    99+
    2024-04-02
  • Android编程如何实现悬浮窗获取并显示当前内存使用量
    这篇文章给大家分享的是有关Android编程如何实现悬浮窗获取并显示当前内存使用量的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。本文实例讲述了Android编程实现悬浮窗获取并显示当前内存使用量的方法,具体如下:...
    99+
    2023-05-30
    android
  • C#实现悬浮窗口的方法详解
    目录一 悬浮窗口二 创建悬浮窗口1 实现细节2 细节三 圆形背景一 悬浮窗口 特点: ① 窗口一般较小,有时为不规则背景; ② 置顶显示; ③ 窗口支持拖动; ④ 一般用于程序状态显...
    99+
    2022-12-21
    C#悬浮窗口 C# 窗口
  • css实现悬浮客服效果的案例
    这篇文章主要介绍css实现悬浮客服效果的案例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!<div class="sideBar">   &nb...
    99+
    2023-06-08
  • android 应用内部悬浮可拖动按钮简单实现代码
    本文介绍了android 应用内部悬浮可拖动按钮简单实现代码,分享给大家,具体如下:可以悬浮在activity上面,在加载fragment时悬浮按钮不会消失实现方式很简单,因为是在应用内部拖动的,只需要通过Activity获取WindowM...
    99+
    2023-05-30
    android 悬浮 拖动
  • 如何在Android应用中使用ScrollView实现悬浮效果
    如何在Android应用中使用ScrollView实现悬浮效果?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。新建一个Android项目,<&#63;xml v...
    99+
    2023-05-31
    android scrollview roi
  • 如何在Android应用中实现一个列表悬浮效果
    这期内容当中小编将会给大家带来有关如何在Android应用中实现一个列表悬浮效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。具体方法如下:package com.xiaos.view;import an...
    99+
    2023-05-31
    android roi
  • 如何使用纯CSS实现类似悬浮窗口的效果
    悬浮窗口是在网页设计中经常使用的一种效果,它可以提供快速访问功能或者展示重要的信息。本文将介绍如何使用纯CSS来实现类似悬浮窗口的效果,包括具体的代码示例。首先,我们需要在HTML中创建一个容器元素,用于承载悬浮窗口的内容。可以是一个div...
    99+
    2023-10-21
    实现 纯CSS 悬浮窗口
  • 怎么在android应用中实现一个RecyclerView悬浮吸顶效果
    本篇文章为大家展示了怎么在android应用中实现一个RecyclerView悬浮吸顶效果,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。MultiType-Adapter打造悬浮吸顶效果注:当前版本...
    99+
    2023-05-31
    android recyclerview recycle
  • Flutter实现增强版的页面悬浮按钮的示例代码
    目录前言SpeedDial 使用总结前言 Flutter 自带的 FloatingActionButton 为我们提供了一个悬浮在顶部的按钮,这个按钮始终在最顶层,因此可以做一些快捷...
    99+
    2023-01-31
    Flutter页面悬浮按钮 Flutter悬浮按钮 Flutter 按钮
  • Android底部弹窗的实现示例代码
    本文主要是介绍Android中实现底部弹窗的的正确姿势,如果你在实现底部弹窗时遇到了一些问题,那么请仔细阅读本文,相信文章会对你有所帮助。收获早知道阅读完本文后,你可以有以下收获 利用PopupWindow实现底部弹窗 PopupWin...
    99+
    2023-05-30
    android 底部弹窗 roi
  • 如何使用CSS content的attr实现鼠标悬浮提示
    这篇文章主要介绍了如何使用CSS content的attr实现鼠标悬浮提示,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。需要那么大的插件库,其实就一两个地方需要做一些提示(t...
    99+
    2023-06-08
  • Android开发Flutter 桌面应用窗口化实战示例
    目录前言一、应用窗口的常规配置应用窗口化自定义窗口导航栏美化应用窗口二、windows平台特定交互注册表操作执行控制台指令实现应用单例三、桌面应用的交互习惯按钮点击态获取应用启动参数...
    99+
    2024-04-02
  • Vue实现悬浮框自由移动+录音功能的示例代码
    目录效果如下主要功能实现1.封装第一个漂浮组件FloatBall.vue2.封装第二个组件录音组件Audio.vue3.recorder.js效果如下 主要功能 1.一个漂浮的球...
    99+
    2024-04-02
  • 使用Android实现一个悬浮在软键盘上的输入栏
    目录前言悬浮栏横屏时软键盘全屏监听软键盘(该方法不可靠,废弃,下面有靠谱的)靠谱的监听软键盘的方法终极悬浮方式如果变小了如果变大了最终代码总结前言 我们要实现一个悬浮在软键盘上的输入...
    99+
    2024-04-02
  • 利用CSS实现图片悬浮效果的技巧和方法
    在网页设计中,图片悬浮效果是一种常见且吸引眼球的设计方式。通过悬浮效果,可以让用户在鼠标悬浮在图片上时,出现一些动画效果、文字说明或者其他有趣的交互效果。本文将介绍一些利用CSS实现图片悬浮效果的技巧和方法,并提供具体的代码示例。放大效果通...
    99+
    2023-10-21
    CSS 效果 图片悬浮
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作