刘海屏
参考
https://blog.csdn.net/yi_master/article/details/80309757
https://stackoverflow.com/questions/53575066/null-window-insets
https://blog.csdn.net/wypeng2010/article/details/81019361
https://blog.csdn.net/xiangzhihong8/article/details/80317682
public class MainActivity extends Activity {
String TAG = "DisplayCutout";
View tv1, tv2,tv3;
DisplayCutoutDemo displayCutoutDemo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
// WindowManager.LayoutParams lp = this.getWindow().getAttributes();
// lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
// lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
// lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
// this.getWindow().setAttributes(lp);
displayCutoutDemo = new DisplayCutoutDemo(this);
displayCutoutDemo.openFullScreenModel();
setContentView(R.layout.activity_main);
displayCutoutDemo.getStatusBarHeight(this);
displayCutoutDemo. controlView(); // 不好用 ,
displayCutoutDemo. f();//可以
tv1 = findViewById(R.id.tv1);
tv2 = findViewById(R.id.tv2);
tv3 = findViewById(R.id.tv3);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) tv1.getLayoutParams();
layoutParams.topMargin = 86;//86 是运行后知道手机的距离顶部安全位置
tv1.setLayoutParams(layoutParams);
FrameLayout.LayoutParams layoutParams3 = (FrameLayout.LayoutParams) tv3.getLayoutParams();
layoutParams3.topMargin = displayCutoutDemo.getStatusBarHeight(this);// 躲开状态栏高度
tv3.setLayoutParams(layoutParams3);
FrameLayout.LayoutParams layoutParams2 = (FrameLayout.LayoutParams) tv2.getLayoutParams();
layoutParams2.leftMargin = 781;//在危险区右侧放置控件,危险区边界获取的不准 😭
tv2.setLayoutParams(layoutParams2);
}
@Override
protected void onStart() {
super.onStart();
Log.d("hwj", "**onStart**" );
displayCutoutDemo. controlView(); //再次onstart后可以获得到值
}
@Override
protected void onResume() {
super.onResume();
Log.d("hwj", "**onResume**" );
displayCutoutDemo. controlView(); //再次onResume后可以获得到值
}
}
package com.jpc.myapplication;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.Log;
import android.view.DisplayCutout;
import android.view.View;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import java.util.List;
/**
* 功能描述: 刘海屏控制
*/
public class DisplayCutoutDemo {
private Activity mAc;
public DisplayCutoutDemo(Activity ac) {
mAc = ac;
}
//在使用LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES的时候,状态栏会显示为白色,这和主内容区域颜色冲突,
//所以我们要开启沉浸式布局模式,即真正的全屏模式,以实现状态和主体内容背景一致
public void openFullScreenModel() {
mAc.requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams lp = mAc.getWindow().getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
mAc.getWindow().setAttributes(lp);
View decorView = mAc.getWindow().getDecorView();
int systemUiVisibility = decorView.getSystemUiVisibility();
int flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
systemUiVisibility |= flags;
mAc.getWindow().getDecorView().setSystemUiVisibility(systemUiVisibility);
}
//获取状态栏高度
public int getStatusBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
Log.d("hwj", "**getStatusBarHeight**" + result);
return result;
}
public void controlView() {
View decorView = mAc.getWindow().getDecorView();
if (decorView != null) {
Log.d("hwj", "**controlView**" + android.os.Build.VERSION.SDK_INT);
Log.d("hwj", "**controlView**" + android.os.Build.VERSION_CODES.P);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
WindowInsets windowInsets = decorView.getRootWindowInsets();
Log.d("hwj", "**controlView**" + windowInsets);
// 第一次启动activiy 时windowInsets是null ,回到桌面后在打开,可以获得到值
if (windowInsets != null) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
DisplayCutout displayCutout = windowInsets.getDisplayCutout();
//getBoundingRects返回List<Rect>,没一个list表示一个不可显示的区域,即刘海屏,可以遍历这个list中的Rect,
//即可以获得每一个刘海屏的坐标位置,当然你也可以用类似getSafeInsetBottom的api
Log.d("hwj", "**controlView**" + displayCutout.getBoundingRects());
Log.d("hwj", "**controlView**" + displayCutout.getSafeInsetBottom());
Log.d("hwj", "**controlView**" + displayCutout.getSafeInsetLeft());
Log.d("hwj", "**controlView**" + displayCutout.getSafeInsetRight());
Log.d("hwj", "**controlView**" + displayCutout.getSafeInsetTop());
}
}
}
}
}
String TAG = "hwj";
public void f() {
mAc.getWindow().getDecorView().setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
DisplayCutout cutout = windowInsets.getDisplayCutout();
if (cutout == null) {
Log.e(TAG, "cutout==null, is not notch screen");//通过cutout是否为null判断是否刘海屏手机
} else {
List<Rect> rects = cutout.getBoundingRects();
if (rects == null || rects.size() == 0) {
Log.e(TAG, "rects==null || rects.size()==0, is not notch screen");
} else {
Log.e(TAG, "rect size:" + rects.size());//注意:刘海的数量可以是多个
for (Rect rect : rects) {
Log.e(TAG, "cutout.getSafeInsetTop():" + cutout.getSafeInsetTop()
+ ", cutout.getSafeInsetBottom():" + cutout.getSafeInsetBottom()
+ ", cutout.getSafeInsetLeft():" + cutout.getSafeInsetLeft()
+ ", cutout.getSafeInsetRight():" + cutout.getSafeInsetRight()
+ ", cutout.rects:" + rect
);
// 打印的结果:cutout.getSafeInsetTop():86, cutout.getSafeInsetBottom():0, cutout.getSafeInsetLeft():0, cutout.getSafeInsetRight():0, cutout.rects:Rect(781, 0 - 1379, 86)
//貌似只能确定缺口底部的安全位置,其他位置都是0,区域好像也不准
}
}
}
return windowInsets;
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" android:orientation="vertical"
android:background="#f0f"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="避开ffffffffffffffffffffffffffffff刘海区" />
<TextView
android:id="@+id/tv3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="避开国国国国国国国国国国国国国国国国刘海区" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="在刘海区右边" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" android:layout_gravity="center"
app:layout_constraintTop_toTopOf="parent" />
</FrameLayout>