1 什么是刘海屏
(1)屏幕的正上方居中位置(下图黑色区域)会被挖掉一个孔,屏幕被挖掉的区域无法正常显示内容,这种类型的屏幕就是刘海屏,也有其他叫法:挖孔屏、凹凸屏等等,这里统一按刘海屏命名。
(2)现在市场上的情况来说,“刘海屏”主要分成两类,一类是标准的 Android P Api,另外一类就是厂商在 Android P 以下的系统,做的特殊适配。
2 刘海屏适配方案
2.1 需要适配刘海屏的页面
(1)对于有状态栏的页面:不会受到刘海屏特性的影响,因为刘海屏包含在状态栏中了;
(2)全屏显示的页面,主要适配的是:①启动页;②引导页;③阅读器,重点是阅读器。
2.2 刘海屏布局及安全区域说明
2.3 参考链接
3 刘海屏适配方案接入步骤(共3步)
3.1 升级Version到28(已修改)
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:design:28.0.0'
compile 'com.android.support:appcompat-v7:28.0.0'
compile 'com.android.support:support-v4:28.0.0'
}
3.2 应用页面设置使用刘海区显示
3.2.1 方案一:在应用的AndroidManifest.xml中增加meta-data属性
此属性不仅可以针对Application生效,也可以对Activity配置生效。弊端:对Application生效,意味着该应用的所有页面,系统都不会做竖屏场景的特殊下移或者是横屏场景的右移特殊处理,也不能针对某页面做特殊处理。
<!-- Android O刘海适配 start -->
<!-- 华为 -->
<meta-data
android:name="android.notch_support"
android:value="true" />
<!-- 华为 -->
<!-- 小米 -->
<meta-data
android:name="notch.config"
android:value="portrait|landscape" />
<!-- 小米 -->
<!-- Android O刘海适配 end -->
<!-- Android全面屏全屏 start -->
<meta-data
android:name="android.max_aspect"
android:value="2.2" />
<!-- Android全面屏全屏 end -->
3.2.2 方案二:动态增加/清除刘海屏flag,请求扩展到刘海区显示/不扩展到刘海区显示
/**
* NotchManager.listenOnChange()
*
* 动态地增加/清除相关的flag,请求使用刘海区显示/不使用刘海区显示
*/
private static void listenOnChange(Activity activity) {
if (mNotchUsable) {
NotchJudgementUtil.addNotchFlag(activity);
} else {
NotchJudgementUtil.clearNotchFlag(activity);
}
}
3.2.3 小书亭的方案——动态增加/清除刘海屏(建议)
(1) 在应用的AndroidManifest.xml中增加meta-data属性
<!-- Android全面屏全屏 start -->
<meta-data
android:name="android.max_aspect"
android:value="2.2" />
<!-- Android全面屏全屏 end -->
(2)使用NotchManager类中的初始化方法:initNotchListener()调用listenOnChange()(initNotchListener()方法已实现);
3.3 在Activity的父类初始化“NotchManager”和添加setFullScreen()方法(已修改)
public class BaseFragmentActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onResume() {
super.onResume();
// 初始化Android O,P刘海屏适配管理类
NotchManager.initNotchListener(this);
}
/**
* 因为刘海屏适配的问题,设置Activity全屏有且只可以使用此方法
*/
public void setFullScreen(boolean fullScreen) {
// 设置是否全屏
if (fullScreen) {
WindowManager.LayoutParams attr = getWindow().getAttributes();
attr.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(attr);
} else {
final WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attrs);
}
// 必须在设置状态栏之后设置,使可以绘制到刘海区域
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
NotchJudgementUtil.setAndroidPDisplayCutoutMode(getWindow(), WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES);
// 设置SystemUi
if (fullScreen) {
View decorView = getWindow().getDecorView();
int systemUiVisibility = decorView.getSystemUiVisibility();
systemUiVisibility |= View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
getWindow().getDecorView().setSystemUiVisibility(systemUiVisibility);
} else {
View decorView = getWindow().getDecorView();
int systemUiVisibility = decorView.getSystemUiVisibility();
systemUiVisibility &= (~View.SYSTEM_UI_FLAG_FULLSCREEN);
systemUiVisibility &= (~View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
systemUiVisibility &= (~View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getWindow().getDecorView().setSystemUiVisibility(systemUiVisibility);
}
}
}
}
4 具体的适配策略(已修改)
4.1 适配启动页
4.1.1 在onCreate()调用setFullScreen(true)
/**
* 在设置全屏的Activity中调用setFullScreen(true)
*/
public class SplashActivity extends BaseFragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 调用父类的setFullScreen方法设置是否全屏
setFullScreen(true);
}
}
4.1.2 启动页添加V28下style主题
<!-- 启动页冷启动适配Android P -->
<style name="XstSplashTheme" parent="XstAppTheme">
// default/shortEdges/never
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
4.1.3 新增drawable-xxhdpi-2034x1080资源文件夹放18:9的占位图
参考链接:全面屏Splash/占位图适配/全面屏/刘海屏笔记
4.2 适配引导页
4.2.1 类似启动页,在onCreate()调用setFullScreen(true)
4.2.2 新增drawable-xxhdpi-2034x1080资源文件夹放18:9的占位图
4.3 适配阅读器
4.3.1 在onCreate()调用setFullScreen(true)(参考)
(1)在onCreate()设置全屏的Activity中调用setFullScreen(true)
public abstract class BaseReadActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// 设置全屏与否
setFullscreen();
}
}
&#