在当前Activity之上创建悬浮view之WindowManager悬浮窗效果
最近有学生做毕业设计,想使用悬浮窗这种效果,其实很简单,我们可以通过系统服务windowmanager来实现此功能,本章我们来试验一下在当前activity之上创建一个悬浮的view。
第一步:认识windowmanager
这个接口用于与 window manager (窗口管理器, 应用框架层) 进行交互。
通过getsystemservice(context.window_service)可以获取到wm的实例.
继承关系
public interface windowmanager implements viewmanager
所属包
android.view.windowmanager
重要方法
addview() 添加view
removeview() 删除view
updateviewlayout () 改变view的参数
window manager service 是全局的,是唯一的。 它将用户的操作,翻译成为指令,发送给呈现在界面上的各个window。activity会将*的控件注册到 window manager 中,当用户真是触碰屏幕或键盘的时候,window manager就会通知到,而当控件有一些请求产生,也会经由viewparent送回到window manager中。从而完成整个通信流程
第二步:重写imageview 的ontouchevent方法
上一步我们知道了 windowmanager可以添加,删除,改变view,那么想要实现悬浮窗的拖动效果我们就要获取imageview的坐标位置。
获取相对屏幕的坐标,即以屏幕左上角为原点
float x = event.getrawx(); float y = event.getrawy()-25; //25是系统状态栏的高度
通过windowmanager.layoutparams wmparams 设置 x ,y
wmparams.x=(int)( x-mtouchstartx); wmparams.y=(int) (y-mtouchstarty);
再通过updateviewlayout()方法设置悬浮窗的当前位置
第三步:加入权限
在androidmanifest.xml中加入如下的权限:
<uses-permission android:name="android.permission.system_alert_window" />
效果如下:
重要代码 : 创建 myapplication
import android.app.application; import android.view.windowmanager; public class myapplication extends application { /** * 创建全局变量 * 注意在androidmanifest.xml中的application节点添加android:name=".myapplication"属性 * */ private windowmanager.layoutparams wmparams=new windowmanager.layoutparams(); public windowmanager.layoutparams getmywmparams(){ return wmparams; } }
创建自定义view 继承imageview
import android.content.context; import android.util.log; import android.view.motionevent; import android.view.windowmanager; import android.widget.imageview; public class myfloatview extends imageview { private float mtouchstartx; private float mtouchstarty; private float x; private float y; private windowmanager wm=(windowmanager)getcontext().getapplicationcontext().getsystemservice(context.window_service); //此wmparams为获取的全局变量,用以保存悬浮窗口的属性 private windowmanager.layoutparams wmparams = ((myapplication)getcontext().getapplicationcontext()).getmywmparams(); public myfloatview(context context) { super(context); // todo auto-generated constructor stub } @override public boolean ontouchevent(motionevent event) { //获取相对屏幕的坐标,即以屏幕左上角为原点 x = event.getrawx(); y = event.getrawy()-25; //25是系统状态栏的高度 log.i("currp", "currx"+x+"====curry"+y); switch (event.getaction()) { case motionevent.action_down: //获取相对view的坐标,即以此view左上角为原点 mtouchstartx = event.getx(); mtouchstarty = event.gety(); break; case motionevent.action_move: updateviewposition(); break; case motionevent.action_up: updateviewposition(); mtouchstartx=mtouchstarty=0; break; } return true; } private void updateviewposition(){ //更新浮动窗口位置参数 wmparams.x=(int)( x-mtouchstartx); wmparams.y=(int) (y-mtouchstarty); wm.updateviewlayout(this, wmparams); } }
创建activity
import android.app.activity; import android.content.context; import android.graphics.pixelformat; import android.os.bundle; import android.util.log; import android.view.gravity; import android.view.view; import android.view.windowmanager; import android.view.view.onclicklistener; import android.view.windowmanager.layoutparams; public class myfloatviewactivity extends activity{ private windowmanager wm=null; private windowmanager.layoutparams wmparams=null; private myfloatview myfv=null; @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); //创建悬浮窗口 createview(); } private void createview(){ myfv=new myfloatview(getapplicationcontext()); myfv.setimageresource(r.drawable.angry_birds); //获取windowmanager wm=(windowmanager)getapplicationcontext().getsystemservice(context.window_service); //设置layoutparams(全局变量)相关参数 wmparams = ((myapplication)getapplication()).getmywmparams(); wmparams.type=layoutparams.type_phone; //设置window type wmparams.format=pixelformat.rgba_8888; //设置图片格式,效果为背景透明 //设置window flag wmparams.flags=layoutparams.flag_not_touch_modal | layoutparams.flag_not_focusable; wmparams.gravity=gravity.left|gravity.top; //调整悬浮窗口至左上角 //以屏幕左上角为原点,设置x、y初始值 wmparams.x=0; wmparams.y=0; //设置悬浮窗口长宽数据 wmparams.width=40; wmparams.height=40; //显示myfloatview图像 wm.addview(myfv, wmparams); } @override public void ondestroy(){ super.ondestroy(); //在程序退出(activity销毁)时销毁悬浮窗口 wm.removeview(myfv); } }
通过以上实例代码给大家详解了在当前activity之上创建悬浮view之windowmanager悬浮窗效果的相关知识,希望本文所述对大家有所帮助。