目录

1.基本介绍

2.代码示例

3.实现效果及便捷工具类

4.仿微信语音通话悬浮窗效果实现

4.1 需求分析及效果展示

4.2 实现

5.最后

1.基本介绍

Android 界面绘制都是通过 WindowManager 服务来实现的,WindowManager 对象可通过获取 WINDOW_SERVICE 系统服务得到,并因为 WindowManager 继承于 ViewManager,所以其拥有以下方法

addView(View view, ViewGroup.LayoutParams params)

主要通过该方法将指定 View 添加到屏幕上,实现悬浮窗效果

( WindowManager 对象调用 addView( ) 入参的 LayoutParams 必须为 WindowManager.LayoutParams )

removeView(View view)

移除指定已添加到屏幕上的 View

updateViewLayout(View view, ViewGroup.LayoutParams params)

通过调整 LayoutParams 更新屏幕上的指定 View

WindowManager 官方文档说明

2.代码示例

1)在 AndroidManifest 中声明权限

2)判断是否拥有在屏幕上层绘制权限

public static boolean canDrawOverlays(Context context, boolean isApplyAuthorization) {

//Android 6.0 以下无需申请权限

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

//判断是否拥有悬浮窗权限,无则跳转悬浮窗权限授权页面

if (Settings.canDrawOverlays(context)) {

return true;

} else {

if (isApplyAuthorization) {

Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + context.getPackageName()));

if (context instanceof Service) {

intent.setFlags(FLAG_ACTIVITY_NEW_TASK);

}

context.startActivity(intent);

return false;

} else {

return false;

}

}

} else {

return true;

}

}

3)获取 WindowManager 对象,生成 WindowManager.LayoutParams ,调用 addView 方法传入指定 View

//获取 WindowManager 服务

WindowManager windowManager = (WindowManager) context.getSystemService(WINDOW_SERVICE);

//生成 WindowManager.LayoutParams 对象

WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();

//形成的窗口层级关系,Android 8.0 前后存在区别

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

//实现在其他应用和窗口上方显示提醒窗口

layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

} else {

//表示提供用户交互操作的非应用窗口

layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;

}

layoutParams.format = PixelFormat.RGBA_8888;

//显示位置

layoutParams.gravity = Gravity.START | Gravity.TOP;

//该flags描述的是窗口的模式,是否可以触摸,可以聚焦等

layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

//窗口宽高

layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT;

layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;

//需要悬浮的指定 View

View view = LayoutInflater.from(context).inflate(R.layout.widget_test_view, null, false);

//将指定 View 添加到屏幕上

windowManager.addView(view, layoutParams);

3.实现效果及便捷工具类

显示效果

MainActivity 代码(Kotlin,点击查看源码)

btn_show_view.setOnClickListener {

if (ExampleFloatingService.isStart) {

//通知处理点击事件

LocalBroadcastManager.getInstance(this)

.sendBroadcast(Intent(ExampleFloatingService.ACTION_CLICK))

} else {

if (FloatingWindowHelper.canDrawOverlays(this, true)) {

startService(Intent(this, ExampleFloatingService::class.java))

}

}

}

ExampleFloatingService 代码(Kotlin,点击查看源码)

悬浮窗管理服务,一般在此处理业务逻辑

目的脱离 Activity 展示悬浮窗

帮助类 FloatingWindowHelper(Java,点击查看源码)

悬浮窗功能相关操作帮助类,使用示例如下

private lateinit var mFloatingWindowHelper: FloatingWindowHelper

private lateinit var mExampleViewA: View

private lateinit var mExampleViewB: View

override fun onCreate() {

super.onCreate()

mFloatingWindowHelper = FloatingWindowHelper(this)

val layoutInflater = LayoutInflater.from(this)

mExampleViewA = layoutInflater.inflate(R.layout.widget_test_view, null, false)

mExampleViewB = layoutInflater.inflate(R.layout.widget_test_view_b, null, false)

}

private fun onClick() {

if (!mFloatingWindowHelper.contains(mExampleViewA)) {

//悬浮显示指定 View

mFloatingWindowHelper.addView(mExampleViewA)

} else if (!mFloatingWindowHelper.contains(mExampleViewB)) {

//悬浮显示指定 View 在指定位置,并可拖动

mFloatingWindowHelper.addView(mExampleViewB, 100, 100, true)

} else {

//移除所有悬浮 View

mFloatingWindowHelper.clear()

}

}

override fun onDestroy() {

mFloatingWindowHelper.destroy()

super.onDestroy()

}

4.仿微信语音通话悬浮窗效果实现

4.1 需求分析及效果展示

仿微信语音通话悬浮窗效果

需求分析:

1.悬浮可拖动

2.自动粘边:停留时只粘在屏幕左边或右边

3.圆直角切换:拖动时悬浮窗四个角为圆角,粘边时粘边处皆为直角

4.2 实现

1.悬浮可拖动

通过 WindowManager addView 实现悬浮效果

通过重写悬浮 View 的 onTouch 方法或为悬浮 View setOnTouchListener 处理触摸事件记录滑动距离,再通过 WindowManager updateViewLayout 方法更新悬浮 View 位置,实现悬浮可拖动效果

2.自动粘边:停留时只粘在屏幕左边或右边

重写悬浮 View 的 onTouch 方法感知触摸事件,当处于触摸移动状态时,更新悬浮 View 四周角为圆角。当触摸抬起时,根据悬浮 View 当前坐标与屏幕宽度值判断位置,然后通过 WindowManager updateViewLayout 方法更新悬浮 View 位置,将悬浮 View 平移到屏幕坐标或右边,实现粘边效果

3.圆直角切换:拖动时悬浮窗四个角为圆角,粘边时粘边处皆为直角

重写悬浮 View 的 onDraw 方法,根据移动方向判断是否需要在左/右边绘制直角矩形覆盖圆角,实现圆直角切换效果

4. 代码示例

自定义悬浮 View (Java,点击查看源码)

调用(Kotlin)

val voiceFloatingView = VoiceFloatingView(context)

voiceFloatingView.show()

5.最后

源码及 Demo 地址:https://github.com/ziwenL/FloatingWindowDemo

如有更好的见解或建议,欢迎留言

android 仿微信来电_Android 悬浮窗功能实现(微信语音通话悬浮窗效果实现)相关推荐

  1. Android 悬浮窗功能实现(微信语音通话悬浮窗效果实现)

    目录 1.基本介绍 2.代码示例 3.实现效果及便捷工具类 4.仿微信语音通话悬浮窗效果实现 4.1 需求分析及效果展示 4.2 实现 5.最后 1.基本介绍 Android 界面绘制都是通过 Win ...

  2. android动画送礼物,Android仿直播类app赠送礼物功能

    直播界面 实现的是播放本地的视频文件: /** * 直播界面,用于对接直播功能 */ public class LiveFrag extends Fragment { private ImageVie ...

  3. android分类功能,Android 仿网易新闻客户端分类排序功能

    先来看看网易新闻客户端以及自己实现的效果图,效果当然还是网易的好 gridviewsort.gif 如何实现拖拽一个Item 用WindowManager添加一个ImageView,并且将这个Imag ...

  4. android仿微博首页布局,Android仿微博首页Tab加号弹窗功能

    本文实例为大家分享了Android微博首页Tab加号弹窗展示的具体代码,供大家参考,具体内容如下 Activity部分的代码 package com.ting.tab; import android. ...

  5. Android 仿新版QQ的tab下面拖拽标记为已读的效果

    可拖拽的红点,(仿新版QQ,tab下面拖拽标记为已读的效果),拖拽一定的距离可以消失回调. GitHub:DraggableFlagView(https://github.com/wangjiegul ...

  6. 阅读软件怎么添加书源_微信聊天怎么添加话题功能?微信聊天添加话题方法[多图]-软件资讯...

    微信大家很熟悉,在不断的研究过程中微信也推出了非常多的实用功能,最近微信又在测试一个新的功能,可以在聊天的过程中添加#号,然后就可以直接关联到有关的信息,行程一个超链接,这样大家就可以直接点击进入一个 ...

  7. android 微信缩小通话界面_Android 悬浮窗功能实现(微信语音通话悬浮窗效果实现)...

    1.基本介绍 Android 界面绘制都是通过 WindowManager 对象可通过获取 WINDOW_SERVICE 系统服务得到,并因为 WindowManager 继承于 ViewManage ...

  8. android仿微博头像_Android仿微信微博多图展示效果

    1.简介 这是一个用于实现像微信朋友圈和微博的类似的九宫格图片展示控件,通过自定义viewgroup实现,使用方便. 多图根据屏幕适配,单张图片时需要自己指定图片的宽高: 2.使用方法 引用: com ...

  9. android 仿今日头条_Android今日头条UI适配完善版

    作者:xcheng_ 链接:https://www.jianshu.com/p/41930fde7aac 前言 众所周知 android的碎片化一直困扰着开发者,我们要花很多的时间去做UI适配的工作. ...

最新文章

  1. java shape_Java 读取shape文件
  2. visual studio 插件开发(5) -- 在任意位置添加自己的菜单
  3. Yii的数值唯一性-场景与SQL
  4. 2top 存储过程 查看_S7-1500 PLC的存储区
  5. 如何把图片转为html,如何将原始十六进制图像转换为html图像
  6. 优化方法-模式搜索法
  7. Python官方文档学习心得(第五篇)
  8. (NO.00005)iOS实现炸弹人游戏(七):游戏数据的序列化表示
  9. 【Kafka】A broker is already registered on the path /brokers/ids/0. This probably indicates that you
  10. 2021高考成绩怎么查询时间北京,2021年北京高考成绩几号公布可以查询,查询时间安排...
  11. lombok工具中@Data注解问题
  12. python字典数据类型笔记_python笔记--数据类型--字典
  13. 给深度学习入门者的Python快速教程 - numpy和Matplotlib
  14. 常用电子产品行业标准及认证
  15. 放大镜 讲课_《放大镜》的教学设计
  16. 关闭”xx程序已停止工作”提示窗口
  17. python组合的语法_在Python中使用语法sugar-to-function组合是个好主意吗?
  18. 怎么查看电脑系统的初始安装日期
  19. 第三届搜狐校园算法大赛开赛!
  20. BZOJ 1911 (APIO 2010) 特别行动队

热门文章

  1. AI人工智能、机器学习、深度学习之间的关系
  2. Centos 升级docker 至最新版本或指定版本
  3. Unity 协程底层原理解析
  4. 【汇正财经】大盘小阳蓄力
  5. 计算两个有序数组的中位数
  6. Netty框架中文编码
  7. day - 13 总结
  8. 如何修改移动终端的wifi(在忘记后台username和password的情况下)
  9. c# RestSharp 发送 x-www-form-urlundecoded 请求
  10. 无盘服务器回写盘用二块和三块有区别,順网无盘对客户机蓝屏做母盘服务器的解决经验总结.doc...