Android WindowManager实现悬浮窗效果 (一)——与当前Activity绑定
最近有学生做毕业设计,想使用悬浮窗这种效果,其实很简单,我们可以通过系统服务WindowManager来实现此功能,本章我们来试验一下在当前Activity之上创建一个悬浮的view。
第一步:认识WindowManager
l 这个接口用于与 window manager (窗口管理器, 应用框架层) 进行交互。
l 通过getSystemService(Context.WINDOW_SERVICE)可以获取到WM的实例.
l 继承关系
public interface WindowManager implements ViewManager
l 所属包
android.view.WindowManager
l 重要方法
addView() 添加view
removeView() 删除view
updateViewLayout () 改变view的参数
Window Manager Service 是全局的,是唯一的。 它将用户的操作,翻译成为指令,发送给呈现在界面上的各个Window。Activity会将顶级的控件注册到 Window Manager 中,当用户真是触碰屏幕或键盘的时候,Window Manager就会通知到,而当控件有一些请求产生,也会经由ViewParent送回到Window Manager中。从而完成整个通信流程
第二步:重写ImageView 的onTouchEvent方法
上一步我们知道了 WindowManager可以添加,删除,改变view,那么想要实现悬浮窗的拖动效果我们就要获取ImageView的坐标位置。
l 获取相对屏幕的坐标,即以屏幕左上角为原点
float x = event.getRawX();
float y = event.getRawY()-25; //25是系统状态栏的高度
l 通过WindowManager.LayoutParams wmParams 设置 x ,y
wmParams.x=(int)( x-mTouchStartX);
wmParams.y=(int) (y-mTouchStartY);
l 再通过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);
}
}
l 最后在程序安装时修改手机里的程序权限-》悬浮窗可用
出处:http://www.cnblogs.com/jerehedu/
版权声明:本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
技术咨询:

Android WindowManager实现悬浮窗效果 (一)——与当前Activity绑定的更多相关文章
- 关于Android WindowManager显示悬浮窗的动画效果
要实现WindowManager添加的窗口,实现动画显示,就需要添加如下红色的属性,其他的添加View只要设置其Animations属性也会实现动画,当然自己实现也可,但是能直接用系统的已经实现好的, ...
- Android仿360手机卫士悬浮窗效果
请看下图: 首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下 ...
- Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果
大家好,今天给大家带来一个仿360手机卫士悬浮窗效果的教程,在开始之前请允许我说几句不相干的废话. 不知不觉我发现自己接触Android已有近三个年头了,期间各种的成长少不了各位高手的帮助,总是有很多 ...
- WindowManager 实现悬浮窗 详解
WindowManager 实现悬浮窗 详解 一:对于想直接看效果的,可以看看我的demo app. 链接:http://sj.qq.com/myapp/detail.htm?apkName=com. ...
- 简易的可拖动的桌面悬浮窗效果Demo
首先,我们需要知道,悬浮窗分为两种:Activity级别的悬浮窗,系统级别的悬浮窗 Activity级别的悬浮窗跟随所属Activity的生命周期而变化,而系统级别的悬浮窗则可以脱离Activity而 ...
- C# WPF QQ新消息托盘悬浮窗效果实现
原文:C# WPF QQ新消息托盘悬浮窗效果实现 今天在做一个项目的时候需要这么一个效果,但是网上找了一会发现并没有现成的给我参考(复制),但是呢,我千(到)辛(处)万(抄)苦(袭)想(复)破(制)头 ...
- Android 桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果
首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下类似的效果. 先谈一下基本的实现原理,这种桌面悬浮窗的效果很 ...
- 【android】来电悬浮窗
先看下效果图 说下思路: 1:监听来电广播 2:根据来电号码,和本地数据库做匹配,有记录的,则提取出头像.名字.职位,生成悬浮窗 3:监听来电广播,如果当前行为是空闲的(没有任何通话行为),则删除掉悬 ...
- android添加桌面悬浮窗
1. 添加权限 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> 2. ...
随机推荐
- [HDU4348]To the moon(主席树+标记永久化)
学可持久化treap的时候才发现自己竟然没写过需要标记下传的主席树,然而现在发现大部分操作都可以标记永久化,下传会增大占用空间. 这题一种写法是和普通的线段树一样标记下传,注意所有修改操作(包括put ...
- Ajax之xmlhttp.open()的用法
1 问题描述: xmlhttp:open方法,请求页面的时候,更新页面数据后,第2次拿到的结果还是上次的信息 2 解决办法: 改用POST方式 3 说明: xmlhttp:open方法 创建一个 ...
- java自动给版本升级,遇9变0且前面一个版本加1
/** * 自动升级版本号,版本号+1 * @param version * @return */ private String autoUpgradeVersion(String version){ ...
- java读取记事本文件第一个字符遇到的一个坑
记事本数据是这样的: Faq_faqTitle=常见问题_标题Faq_faqKeyword=关键字Faq_faqDescription=FAQ描述...... 文件编码:utf-8有签名 然后用jav ...
- 下载8000首儿歌的python代码
下载8000首儿歌的python的代码: #-*- coding: UTF-8 -*- from pyquery import PyQuery as py from lxml import etree ...
- 积跬步,聚小流-------js实现placeholder的效果
前几天在"技术问答"上问了问题,然后有回复一句话就给概括了:placeholder的效果,不得不说.了解的多了才干说起来言简意赅,用最简单的语言描写叙述最清晰的表达. 可是plac ...
- 交叉编译Python-3.6.0到aarch64/aarch32 —— 支持sqlite3
参考 https://datko.net/2013/05/10/cross-compiling-python-3-3-1-for-beaglebone-arm-angstrom/ 平台 主机: ubu ...
- Delphi 局域网点对点文件传输(IdTcpClient控件)
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- iOS 获取本地视频的缩略图
+(UIImage *)getImage:(NSString *)videoURL { AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSU ...
- 设计模式之代理模式之二(Proxy)
from://http://www.cnblogs.com/xwdreamer/archive/2012/05/23/2515306.html 设计模式之代理模式之二(Proxy) 0.前言 在前 ...