当前位置:   article > 正文

android自定义窗口层级(自定义车载系统中倒车影像显示层级)_安卓修改displayframes大小

安卓修改displayframes大小

在车载系统或者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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

定义@ViewDebug.ExportedProperty注解:

        @ViewDebug.ExportedProperty(mapping = {
                ···代码省略           
                @ViewDebug.IntToString(from = TYPE_CAR_PREVIEW,
                        to = "TYPE_CAR_PREVIEW"),
        })
        public int type;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

定义@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);
        } 
        ...代码省略
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

启动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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

当然可以增加许多自定义的Window Type,可以自定义范围TYPE_CUSTOM_LASTTYPE_CUSTOM_FIRST,但不要超过LAST_SYSTEM_WINDOW

/**
         * End of types of system windows.
         */
        public static final int LAST_SYSTEM_WINDOW      = 2999;
  • 1
  • 2
  • 3
  • 4

同时自定义全屏逻辑,这样就可以在系统应用中使用此类型了。

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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/325834
推荐阅读
相关标签
  

闽ICP备14008679号