Android刘海屏适配及view被摄像头遮挡动态改变位置( 二 )


/*** 判断OPPO是否有刘海屏** @param context Context* @return 是否有刘海屏*/private static boolean hasNotchAtOPPO(@NonNull Context context) {return context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");}
三. 设置异形屏的显示模式
还允许我们控制是否在刘海区域内显示内容 。窗口布局属性 tMode 控制您的内容如何呈现在刘海区域中 。您可以将 tMode 设为以下某个值:
- 这是默认行为,在竖屏模式下,内容会呈现到刘海区域中;但在横屏模式下,内容会显示黑边 。
S - 在竖屏模式和横屏模式下,内容都会呈现到刘海区域中 。
- 内容从不呈现到刘海区域中 。
/*** 设置异形屏的显示模式**@param activity Activity*@param int mode(三种模式)*/public static void setWindowLayoutInDisplayCutoutMode(Activity activity,int mode) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {WindowManager.LayoutParams lp = activity.getWindow().getAttributes();lp.layoutInDisplayCutoutMode = mode;activity.getWindow().setAttributes(lp);}}

Android刘海屏适配及view被摄像头遮挡动态改变位置

文章插图
四. 判断view是否被摄像头遮挡
刘海屏的摄像头可能在左边、中间、右边,我们可以通过.()获取所有缺口的集合,然后根据缺口的位置判断view是否被遮挡 。
/**** 判断view是否被摄像头遮挡*/public static boolean isViewCovered(Activity activity,View view) {//判断是否是异形屏(里面包含Android P以上及以下异形屏的判断)if (isSpecialshapedScreen(activity) && isAndroidP(activity)) {List rects = displayCutout.getBoundingRects();int rectLfet = rects.get(0).left;int rectRight = rects.get(0).right;int rectTop = rects.get(0).top;int rectBottom = rects.get(0).bottom;int[] location = newint[2] ;view.getLocationOnScreen(location); //获取在整个屏幕内的绝对坐标,含statusBarint width = view.getWidth();int height = view.getHeight();int left = location[0];int right = location[0] + width;int top = location[1];int bottom = location[1] + height;if (((bottom <= rectBottom && bottom > rectTop) || (top < rectBottom && top >= rectTop))&& ((right > rectLfet && right <= rectRight)|| (left >= rectLfet && right <= rectRight)|| (left >= rectLfet && left < rectRight)|| (left < rectLfet && right > rectRight))) {return true;} else if (((left >= rectLfet && left < rectRight) || (right > rectLfet && right <= rectRight))&& ((bottom > rectTop && bottom <=rectBottom)|| (top >= rectTop && bottom <= rectBottom)|| (top >= rectTop && top < rectBottom)|| (top < rectTop && bottom > rectBottom))) {return true;} else if (left <= rectLfet && right >= rectRight && top <= rectTop && bottom >= rectBottom) {return true;}}return false;}
分析: left 、top、right、分别代表view在屏幕中的左上右下距离 。、、、分别代表刘海屏在屏幕中的左上右下距离 。
1.以view的上边或下边为边界,上边或下边在刘海屏的上下之间,view被遮挡的情况有四种 。
2.以view的左边或右边为边界,左边或右边在刘海屏的左右之间,view被遮挡的情况有四种 。
3.刘海屏被view包围
五. 动态改变view的位置
当我们判断view被刘海屏遮挡后,就可以改变view的位置,根据需求移动到刘海屏下方或其他 。可以通过设置,要想获取到view在屏幕中的位置,需要等view绘制完成,所以使用view.post
/** *伪代码*/view.post(new Runnable() {@Overridepublic void run() {if (isViewCovered(activity,view) ) {List rects = cutoutDisp.getBoundingRects();int rectBottom = rects.get(0).bottom;FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams();layoutParams.topMargin = mMenu.getTop() + rectBottom;mMenu.setLayoutParams(layoutParams);}}});
【Android刘海屏适配及view被摄像头遮挡动态改变位置】