刘海屏从Iphone 8开始,这股风慢慢吹到了Android平台,目前市面上的刘海屏主要集中在高版本的高端机器上,国内主要以华为P20,Vivo,Oppo最新旗舰机在引领刘海屏,刘海屏如下图:
在刘海屏之前先了解一下标题栏和状态栏,状态栏就是App中最上面的那一栏,显示信号、电量等状态信息,标题栏一般显示App名称,返回键按钮等,Android3.0叫ActionBar,5.0又推出ToolBar,使用support包可以在4.0的版本上使用ToolBar。下图中,深蓝色的为状态栏,浅蓝色带“App”字样的为标题栏。
在对刘海屏进行适配时,如果界面状态栏和标题栏都存在的情况下,界面会自动适配,不需要再做过多的适配设置,如果状态栏和标题栏都隐藏,开发者就需要考虑刘海屏的适配问题。下面对状态栏和标题栏隐藏进行说明。
父Activity为Activity
对于继承自Acitivity的,隐藏标题栏可以通过如下代码,需要注意代码需要放在setContentView()之前,否则没效果:
requestWindowFeature(Window.FEATURE_NO_TITLE);
也可以通过在AndroidManifest中对Application或者Activity中对Theme进行设置,来隐藏状态栏区别是Application是对整个应用起作用,即所有Activity;Activity只对当前Activity起作用。
android:theme="@android:style/Theme.Black.NoTitleBar"
关于隐藏状态栏,网上都说通过如下代码进行设置,本人进行了真机测试发现和全屏一样,即将状态栏和标题栏一起隐藏了,隐藏直接跳过隐藏状态栏。
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
隐藏状态栏和标题栏通过如下代码设置,同样代码需要放在setContentView()之前,否则没效果
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
也可以在AndroidManifest中设置Theme,将状态栏和标题栏隐藏:
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
父Activity为AppCompatActivity
在Android Studio中创建的Activity默认是继承AppCompatActivity,AppCompatActivity使用如下代码,只能隐藏状态栏,无法将标题栏隐藏
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
要想将标题栏隐藏可以再加一行代码:
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
actionBar.hide();
最终代码为:
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
actionBar.hide();
注意代码的前后顺序,注意代码的顺序,注意代码的顺序,重要的事说三遍。
在Activity中通过代码隐藏玩状态栏之后
对于AppCompatActivity同样可以对Theme进行设置,来隐藏状态栏和标题栏,在Theme中添加如下两行代码即可实现:
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
刘海屏适配
状态栏和标题栏告一段落,现在来讲一下刘海屏适配问题。刘海屏分为三种情况:
- 有状态栏页面,不会受到刘海影响
- 无状态栏页面,未适配刘海
-
无状态栏页面,适配刘海
从上面三张图片可以明显看出区别,刘海屏适配分为两种方案,一种是按照Google官方,另一种就是各个手机厂商自己的。由于Google官方需要SDK_INT >=28,也就是Android P才能使用,所以目前还无法进行实测。所以本文主要以第二种方案进行实测。
华为刘海屏适配方案:
http://mini.eastday.com/bdmip/180411011257629.html
Oppo刘海屏适配方案:
https://open.oppomobile.com/wiki/doc#id=10139
Vivo刘海屏适配方案
https://dev.vivo.com.cn/doc/document/info?id=103
本文以华为P20 Pro为测试机进行了适配方案实测,首先按照上面描述的将页面进行全屏设置,将状态栏和标题栏进行隐藏,界面显示为:
根据官方刘海屏适配,在AndroidManifest中对Application或者Activity添加如下代码:
<meta-data
android:name="android.notch_support"
android:value="true" />
或者在Activity中使用代码设置:
/*刘海屏全屏显示FLAG*/
public static final int FLAG_NOTCH_SUPPORT=0x00010000;
/**
* 设置应用窗口在华为刘海屏手机使用刘海区
* @param window 应用页面window对象
*/
public static void setFullScreenWindowLayoutInDisplayCutout(Window window) {
if (window == null) {
return;
}
WindowManager.LayoutParams layoutParams = window.getAttributes();
try {
Class layoutParamsExCls = Class.forName("com.huawei.android.view.LayoutParamsEx");
Constructor con=layoutParamsExCls.getConstructor(LayoutParams.class);
Object layoutParamsExObj=con.newInstance(layoutParams);
Method method=layoutParamsExCls.getMethod("addHwFlags", int.class);
method.invoke(layoutParamsExObj, FLAG_NOTCH_SUPPORT);
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException |InstantiationException
| InvocationTargetException e) {
Log.e("test", "hw add notch screen flag api error");
} catch (Exception e) {
Log.e("test", "other Exception");
}
}
最终适配刘海屏实测结果为:
主意观察显示的Button,由于适配了刘海屏,导致Button显示不全。因此开发人员还要进行UI的适配,尽量调整布局避开刘海区,布局原则:保证重要的文字、图片和视频信息、可点击的控件和图标还有应用弹窗等等布局建议显示在状态栏区域以下(安全区域);不重要,遮挡不会出现问题的布局可以延伸到状态栏区域(危险区域)显示。