在Android的开发过程中,我们经常会使用的一些悬浮窗效果,例如Android本身就提供了Dialog等控件来实现,但是在很多情况下,我们需要更加灵活的使用方式,比如完全自定义浮出窗口中所需要显示的内容等,这个时候我们就会用到WindowManager.addView的方式来显示一个自定义的window。
代码例如:
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mParams = new WindowManager.LayoutParams();
mParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
int flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
mParams.flags = flags;
mParams.format = PixelFormat.TRANSLUCENT;
mParams.width = LayoutParams.MATCH_PARENT;
mParams.height = LayoutParams.MATCH_PARENT;
mParams.gravity = Gravity.CENTER;
mWindowManager.addView(mView, params);
但是,如果你的这个View需要显示很多动画效果,又例如需要使用一些容器类控件例如ListView来显示很多内容,此时会发现动画的效果、流畅度、帧率(fps)相比直接使用activity要差很多,同样都是View,那这是为什么了?
原来,这一切都是由于没有开启硬件加速所导致,在Android API Level 14以上的所有版本,不管你是否在ManiFest中配置过,都是默认开启应用级别的硬件加速的。而Activity在显示系统中来看,其实也是一个Window,但是这个Window确是默认就开启了硬件加速的,而使用此时我们的悬浮窗(Window)确是没有开启的,因此只需要做一点点改动,就可以解决上述的问题?
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mParams = new WindowManager.LayoutParams();
mParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
*int flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM|
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;*
mParams.flags = flags;
mParams.format = PixelFormat.TRANSLUCENT;
mParams.width = LayoutParams.MATCH_PARENT;
mParams.height = LayoutParams.MATCH_PARENT;
mParams.gravity = Gravity.CENTER;
mWindowManager.addView(mView, params);
在flags中,我们加入了WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,这样就能打开悬浮窗的硬件加速绘制了,硬件加速开启后,Android的显示系统就会采取使用硬件渲染的方式来实现绘制,这样就能达到客户端想要的动画等一系列的效果了。