Android开发笔记(一百一十八)自定义悬浮窗

这篇博客探讨了在Android开发中如何创建和管理悬浮窗,包括使用WindowManager实现静态和动态悬浮窗的详细步骤,是理解Android悬浮窗机制的重要参考资料。
摘要由CSDN通过智能技术生成

WindowManager

在前面《 Android开发笔记(六十六)自定义对话框》中,我们提到每个页面都是一个Window窗口,许多的Window对象需要一个管家来打理,这个管家我们称之为WindowManager窗口管理。在手机屏幕上新增或删除页面窗口,都可以归结为WindowManager的操作,下面是该管理类的常用方法说明:
getDefaultDisplay : 获取默认的显示屏信息。通常用该方法获取屏幕分辨率,详情参见《 Android开发笔记(三)屏幕分辨率》。
addView : 往窗口添加视图。第二个参数为WindowManager.LayoutParams对象。
updateViewLayout : 更新指定视图的布局参数。第二个参数为WindowManager.LayoutParams对象。
removeView : 往窗口移除指定视图。


下面是窗口布局参数WindowManager.LayoutParams的常用属性说明:
format : 窗口的像素点格式。取值见PixelFormat类中的常量定义,一般取值PixelFormat.RGBA_8888。
type : 窗口的显示类型,常用的类型说明如下:
--TYPE_SYSTEM_ALERT : 系统警告提示。
--TYPE_SYSTEM_ERROR : 系统错误提示。
--TYPE_SYSTEM_OVERLAY : 页面顶层提示。
--TYPE_SYSTEM_DIALOG : 系统对话框。
--TYPE_STATUS_BAR : 状态栏
--TYPE_TOAST : 短暂通知Toast
flags : 窗口的行为准则,常用的标志位如下说明(对于悬浮窗来说,一般只需设置FLAG_NOT_FOCUSABLE):
--FLAG_NOT_FOCUSABLE : 不能抢占焦点,即不接受任何按键或按钮事件。
--FLAG_NOT_TOUCHABLE : 不接受触摸屏事件。悬浮窗一般不设置该标志,因为一旦设置该标志,将无法拖动悬浮窗。
--FLAG_NOT_TOUCH_MODAL : 当窗口允许获得焦点时(即没有设置FLAG_NOT_FOCUSALBE标志),仍然将窗口之外的按键事件发送给后面的窗口处理。否则它将独占所有的按键事件,而不管它们是不是发生在窗口范围之内。
-- : 
--FLAG_LAYOUT_IN_SCREEN : 允许窗口占满整个屏幕。
--FLAG_LAYOUT_NO_LIMITS : 允许窗口扩展到屏幕之外。
--FLAG_WATCH_OUTSIDE_TOUCH : 如果设置了FLAG_NOT_TOUCH_MODAL标志,则当按键动作发生在窗口之外时,将接收到一个MotionEvent.ACTION_OUTSIDE事件。
alpha : 窗口的透明度,取值为0-1。
gravity : 取值同View的setGravity方法。
x : 窗口左上角的X坐标。
y : 窗口左上角的Y坐标。
width : 窗口的宽度。
height : 窗口的高度。


静态悬浮窗

悬浮窗有点类似对话框,它们都是独立于Activity页面的窗口,但是悬浮窗又有一些与众不同的特性,例如:
1、悬浮窗是可以拖动的,对话框则不能;
2、悬浮窗不妨碍用户触摸窗外的区域,对话框则不让用户操作框外的控件;
3、悬浮窗独立于Activity页面,即当页面退出后,悬浮窗仍停留在屏幕上;而对话框与Activity页面是共存关系,一旦页面退出则对话框也消失了;


基于悬浮窗的以上特性,我们要实现窗口的悬浮效果,就不仅仅是调用WindowManager的addView方法那么简单了,而是需要做一系列的自定义处理,具体步骤如下:
1、在AndroidManifest.xml中声明系统窗口权限,即增加下面这句:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
2、在自定义的悬浮窗控件中,要设置触摸监听器,并根据用户的手势滑动来相应调整窗口位置,以实现悬浮窗的拖动功能;
3、合理设置悬浮窗的窗口参数,主要是把窗口参数的显示类型设置为TYPE_SYSTEM_ALERT或者TYPE_SYSTEM_ERROR,另外要设置标志位FLAG_NOT_FOCUSABLE;
4、在构造悬浮窗实例时,要传入Application的上下文Context,这是为了保证即使退出Activity,也不会关闭悬浮窗。因为Application对象在app运行过程中是始终存在着的,而Activity对象只在打开页面时有效,一旦退出页面则Activity的上下文就立刻回收(这会导致依赖于该上下文的悬浮窗也一块被回收了)。


下面是一个静态悬浮窗的效果截图:



下面是自定义悬浮窗的示例代码:
import android.content.Context;
import android.graphics.PixelFormat;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

public class FloatView extends View {
	private final static String T
评论 65
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值