赞
踩
在车载系统或者TV系统中,通过WindowManager添加一个窗口时,又由于存在多个应用添加窗口,且用的同一窗口层级,会出现相互覆盖的情况。这时可以考虑自定义一个更高层级的Window Type来避免覆盖问题。
例如android车载系统中,倒车影像是最高的优先级,需要优先显示,这时可以自定义一个TYPE_CAR_PREVIEW
的窗口层级来保证倒车影像的优先显示。具体步骤如下:
1.首先从WindowManager
入手,源码路径:
frameworks\base\core\java\android\view\WindowManager
定义Window Type,在TYPE_APPLICATION_OVERLAY
基础上再加1,即为2039。
/**
* Start of system-specific window types. These are not normally
* created by applications.
*/
public static final int FIRST_SYSTEM_WINDOW = 2000;
···代码省略···
/**
* Window type: BACK CAR PREVIEW.
* @hide
*/
public static final int TYPE_CAR_PREVIEW= FIRST_SYSTEM_WINDOW + 39;
定义@ViewDebug.ExportedProperty
注解:
@ViewDebug.ExportedProperty(mapping = {
···代码省略
@ViewDebug.IntToString(from = TYPE_CAR_PREVIEW,
to = "TYPE_CAR_PREVIEW"),
})
public int type;
定义@ViewDebug.ExportedProperty
注解注解后可以在android提供的工具Monitor(或已经废弃的DDMS)中的Hierarchy Viewer中调试View的属性。
ViewDebug.ExportedProperty相关请参考此篇:@ViewDebug.ExportedProperty的使用
2.设置对应窗口层级全屏,在PhoneWindowManager.java
中进行全屏设置。
源码路径:
frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java
android系统全屏时为Overscan。所谓Overscan区域,就是电视机屏幕四周某些不可见的区域,这是电视机的特性。并且,Overscan的具体值也没有一个明确的标准,不同的电视机厂家的Overscan的值也各不相同。具体参考Overscan的概念:Overscan介绍。
PhoneWindowManager中的全屏的相关代码下:
自定义Window Type还需要考虑全屏的问题,在源码的layoutWindowLw
方法中设置全屏。
@Override
public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) {
...代码省略
final Rect pf = mTmpParentFrame;
final Rect df = mTmpDisplayFrame;
final Rect of = mTmpOverscanFrame;
final Rect cf = mTmpContentFrame;
...代码省略
if(attrs.type == WindowManager.LayoutParams.TYPE_CAR_PREVIEW) {
// Back Car Preview hign layer window always full screen.
//forceFullScreen
cf.set(displayFrames.mOverscan);
of.set(displayFrames.mOverscan);
df.set(displayFrames.mOverscan);
pf.set(displayFrames.mOverscan);
}
...代码省略
}
启动ParentFrame、DisplayFrame、OverscanFrame、ContentFrame代表屏幕画面的大小。
containing—>mContainingFrame,在全屏显示的时候该值和parentFrame是一样的。parent—>mParentFrame:指的是父窗口的大小。
display---->mDisplayFrame,默认情况下是指整个显示屏幕,也就是屏幕的大小。overscan----->mOverscanFrame,设备的屏幕大小。
content----->mContentFrame,窗口的内容区域大小。
visible—>mVisibleFrame,可见区域大小。
decor---->mDecorFrame,装饰区域大小,除去状态栏和导航栏。
在WindowState.java中有关于这几个Frame帧的简单介绍,源码地址:
frameworks\base\services\core\java\com\android\server\wm\WindowState.java
描述如下:
final Rect mContainingFrame = new Rect();
final Rect mParentFrame = new Rect();
/** Whether the parent frame would have been different if there was no display cutout. */
private boolean mParentFrameWasClippedByDisplayCutout;
// The entire screen area of the {@link TaskStack} this window is in. Usually equal to the
// screen area of the device.
final Rect mDisplayFrame = new Rect();
// The region of the display frame that the display type supports displaying content on. This
// is mostly a special case for TV where some displays don’t have the entire display usable.
// {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_OVERSCAN} flag can be used to allow
// window display contents to extend into the overscan region.
private final Rect mOverscanFrame = new Rect();
// The display frame minus the stable insets. This value is always constant regardless of if
// the status bar or navigation bar is visible.
private final Rect mStableFrame = new Rect();
// The area not occupied by the status and navigation bars. So, if both status and navigation
// bars are visible, the decor frame is equal to the stable frame.
final Rect mDecorFrame = new Rect();
// Equal to the decor frame if the IME (e.g. keyboard) is not present. Equal to the decor frame
// minus the area occupied by the IME if the IME is present.
private final Rect mContentFrame = new Rect();
当然可以增加许多自定义的Window Type,可以自定义范围TYPE_CUSTOM_LAST
和TYPE_CUSTOM_FIRST
,但不要超过LAST_SYSTEM_WINDOW
。
/**
* End of types of system windows.
*/
public static final int LAST_SYSTEM_WINDOW = 2999;
同时自定义全屏逻辑,这样就可以在系统应用中使用此类型了。
3.在应用中使用自定义Window Type
private WindowManager.LayoutParams mLayoutParams;
mLayoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_CAR_PREVIEW);
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
mLayoutParams.format = PixelFormat.RGBA_8888;
mLayoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
mLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。