最近有学生做毕业设计,想使用悬浮窗这种效果,其实很简单,我们可以通过系统服务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绑定的更多相关文章

  1. 关于Android WindowManager显示悬浮窗的动画效果

    要实现WindowManager添加的窗口,实现动画显示,就需要添加如下红色的属性,其他的添加View只要设置其Animations属性也会实现动画,当然自己实现也可,但是能直接用系统的已经实现好的, ...

  2. Android仿360手机卫士悬浮窗效果

    请看下图:                         首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下 ...

  3. Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果

    大家好,今天给大家带来一个仿360手机卫士悬浮窗效果的教程,在开始之前请允许我说几句不相干的废话. 不知不觉我发现自己接触Android已有近三个年头了,期间各种的成长少不了各位高手的帮助,总是有很多 ...

  4. WindowManager 实现悬浮窗 详解

    WindowManager 实现悬浮窗 详解 一:对于想直接看效果的,可以看看我的demo app. 链接:http://sj.qq.com/myapp/detail.htm?apkName=com. ...

  5. 简易的可拖动的桌面悬浮窗效果Demo

    首先,我们需要知道,悬浮窗分为两种:Activity级别的悬浮窗,系统级别的悬浮窗 Activity级别的悬浮窗跟随所属Activity的生命周期而变化,而系统级别的悬浮窗则可以脱离Activity而 ...

  6. C# WPF QQ新消息托盘悬浮窗效果实现

    原文:C# WPF QQ新消息托盘悬浮窗效果实现 今天在做一个项目的时候需要这么一个效果,但是网上找了一会发现并没有现成的给我参考(复制),但是呢,我千(到)辛(处)万(抄)苦(袭)想(复)破(制)头 ...

  7. Android 桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果

    首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下类似的效果. 先谈一下基本的实现原理,这种桌面悬浮窗的效果很 ...

  8. 【android】来电悬浮窗

    先看下效果图 说下思路: 1:监听来电广播 2:根据来电号码,和本地数据库做匹配,有记录的,则提取出头像.名字.职位,生成悬浮窗 3:监听来电广播,如果当前行为是空闲的(没有任何通话行为),则删除掉悬 ...

  9. android添加桌面悬浮窗

    1. 添加权限 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> 2. ...

随机推荐

  1. 五校联考R1 Day1T3 平面图planar(递推 矩阵快速幂)

    题目链接 我们可以把棱柱拆成有\(n\)条高的矩形,尝试递推. 在计算的过程中,第\(i\)列(\(i\neq n\))只与\(i-1\)列有关,称\(i-1\)列的上面/下面为左上/左下,第\(i\ ...

  2. 2016 Multi-University Training Contest 6 题解

    我只能说: A Boring Question 下面公式重复了一行 \[ \sum\_{0\leq k\_{1},k\_{2},\cdots k\_{m}\leq n}\prod\_{1\leq j& ...

  3. SQL Server Management Studio 教程二: 创建新登录名

    1.先用windows身份登录SQL server2008 2.打开[安全性],右击[登录名],选择[新建登录名] 3.[常规]选项页面中,修改如下位置设置,默认数据库可以是其他数据库,不一定是mas ...

  4. FireDAC 下的 Sqlite [8] - 自定义函数

    Sqlite 本身没有这个功能, FireDAC 通过 TFDSQLiteFunction 增加了该功能; 尽管通过某些 SQL 语句或通过视图也可以达到类似效果, 但函数会更灵活些. 本例先建了一个 ...

  5. 安装node.js / npm / express / KMC

    http://www.cnblogs.com/seanlv/archive/2011/11/22/2258716.html 1. 下载Node.js官方Windows版程序: http://nodej ...

  6. LINUX 内核守护进程

    http://alfred-sun.github.io/blog/2015/06/18/daemon-implementation/

  7. IIS发布以后,handle文件找不到,404错误

    昨天碰到一个奇怪问题,开发环境没有问题,发布到IIS7.5以后,保存操作不能成功,跟踪发现,是handle方法找不到,抛错. 想了很多方法,最后把怀疑是GET方式和客户数据引起的问题,改成POST方式 ...

  8. MongoDB C# 驱动的各种版本下载地址

    https://github.com/mongodb/mongo-csharp-driver/releases

  9. SpringBoot集成JWT实现token验证

    原文:https://www.jianshu.com/p/e88d3f8151db JWT官网: https://jwt.io/ JWT(Java版)的github地址:https://github. ...

  10. ASIHTTPRequest系列(一):同步和异步请求

    ASIHTTPRequest系列(一):同步和异步请求 发表于8个月前(2013-11-27 19:21)   阅读(431) | 评论(0) 6人收藏此文章, 我要收藏 赞0 ASIHTTPRequ ...