您的位置:首页 > 其它

使用WindowManager添加View——悬浮窗口的基本原理

2016-01-11 15:41 344 查看
Android系统中的“窗口”类型虽然很多,但只有两大类是经常使用的:一是由系统进程管理的,称之为“系统窗口”;第二个就是由应用程序产生的,用于显示UI界面的“应用窗口”。如果大家熟悉WindowManagerService(窗口管理机制WMS)的话,那么一切都很简单。它是一个负责统筹管理所有窗口的一个服务,从始到终一直在运作。之所以扯上WMS,因为它才是大Boss,所有的窗口变化都要通知到它。而WindowManager虽然与它没有之间的关系,但是对它负责,所有信息会经过一定的途径传回到WMS中。[b]额,跑题了,我们说的是WindowManager,它是一个接口类,它可以实现对view的管理,包括增加,更新和删除。[/b]

 

[b]一、[b][b]WindowManager[/b][/b][/b]

获取WindowManager

wManager = (WindowManager) getApplicationContext().getSystemService(
Context.WINDOW_SERVICE);


在Activity和Service中都可以直接使用这个方法来获得WindowManager。其getSystemService返回的是一个WindowManagerImpl对象,这是一个存在于本地进程中的一个对象。而事实是WindowManagerImpl继承了WindowManager,而WindowManger继承了ViewManager。

设置WindowManager.LayoutParams
LayoutParams里面存放着的是窗口的属性,通过这个变量,可以为窗口赋予各式的属性。也可以改变它的属性值,来进行各种各样的操作,像悬浮窗口的拖动,拉伸等操作。

详细的属性表在:
http://www.cnblogs.com/shitianzeng/articles/2814050.html
WindowManager的操作
(1)窗口添加

public void addView(View view, ViewGroup.LayoutParams params);


(2)窗口更新

public void updateViewLayout(View view, ViewGroup.LayoutParams params);


(3)窗口删除

public void removeView(View view);


以上的三个方法都存在于ViewManager中。

[b]二、[b][b]悬浮窗实例
          例子设计:利用service打开悬浮窗,其中放着一个自定义的View,点击消除悬浮窗。
[/b][/b][/b]

首先是Service,它是由Activity打开。先获得WindowManager,再配置属性

public class WindowService extends Service implements OnClickListener {

private WindowManager wManager;// 窗口管理者
private WindowManager.LayoutParams mParams;// 窗口的属性
private MyView myView;
private boolean flag = true;

@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}

@Override
public void onCreate() {
// TODO Auto-generated method stub
wManager = (WindowManager) getApplicationContext().getSystemService( Context.WINDOW_SERVICE);
mParams = new WindowManager.LayoutParams();
mParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;// 系统提示window
mParams.format = PixelFormat.TRANSLUCENT;// 支持透明
//mParams.format = PixelFormat.RGBA_8888;
mParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 焦点
mParams.width = 490;//窗口的宽和高
mParams.height = 160;
mParams.x = 0;//窗口位置的偏移量
mParams.y = 0;
//mParams.alpha = 0.1f;//窗口的透明度
myView = new MyView(this);
myView.setOnClickListener(this);
super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
if (flag) {
flag = false;
wManager.addView(myView, mParams);//添加窗口
}
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
// TODO Auto-generated method stub
if (myView.getParent() != null)
wManager.removeView(myView);//移除窗口
super.onDestroy();
}

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (v.equals(myView)) {
flag = true;
if (myView.getParent() != null)
wManager.removeView(myView);//移除窗口
}
}

}


 

一个自定义的view

很早以前写的surfaceView,里面包括文字图片的两个显示动画


看看就行了

Activity中,点击打开service

@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.d("CPACM","onTouchEvent");
Intent intent = new Intent();
intent.setClass(this, WindowService.class);
startService(intent);
this.finish();
return super.onTouchEvent(event);
}


manifest.xml

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 使用SYSTEM_ALERT_WINDOW时必须要加 -->


 

效果图


 



[b]三、[b][b]结束语
[/b][/b][/b]学到越深,发现需要学的越多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: