说明:这篇文章主要解决android启动页图片全屏时图片被拉伸问题
需求:
最近app全面改版,然后启动页换成了一整张图片,效果图如下:
2、问题
刚开始的时候,切的是一整张图,然后在两部测试机下测试发现,启动的时候:
①、底部的字体有稍微的变形;
②、图片垂直方向有些许的压缩【这个问题在改版之前有,测试没有提这个问题,但是在这次改版的时候,想要进一步优化一下,启动时感觉是两张图片的这种体验不是很好】;
3、解决
(需要注意的是,启动页的图片尺寸大小的选择也是很影响到不同手机的适配的,目前我选择的图片的尺寸大小是1125 × 1884大小的,放在mipmap-xxhdpi文件夹下的,这个尺寸在目前公司测试机上适配都是OK的)
问题①解决方法:
下半部分字体为了防止变形,让设计把效果图切成了两部分,上面图片部分和下面的纯文字部分,切图如下:
更进一步优化的话,可以对图片进行.9的适配
问题②解决方法:
图片被压缩,经过多次测试发现,是因为在Activity里面设置了沉浸式效果,导致图片没有全屏展示,在代码中去掉了沉浸式效果,然后在styles.xml里对启动页进行主题设置,使布局占据状态栏空间
清单文件代码
<activity
android:name=".ui.other.SplashActivity"
android:enabled="false"
android:alwaysRetainTaskState="true"
android:theme="@style/SplashTheme"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
主题文件代码
<!--android9.0启动页全屏适配-->
<!--!!!注意,这里修改,记得同步values-v27里面的样式文件-->
<style name="SplashTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item><!--目前这个属性未知-->
<item name="android:windowIsTranslucent">false
</item><!--沉浸透明状态栏 可选,窗口是否是半透明,设置状态栏的效果,这个值也会影响状态效果-->
<item name="android:windowDisablePreview">false
</item><!--冷启动是用到的属性,窗口不可见时的预览图,为true时点击app图标会慢一会-->
<item name="android:windowBackground">@drawable/layer_launch2</item><!--替换启动白屏的图片-->
<!--<item name="android:windowBackground">@mipmap/ic_splash_logo</item>--><!--替换启动白屏的图片-->
<!-- 在5.0后,增加了一个windowDrawsSystemBarBackgrounds属性,用来标志此窗口是否负责绘制系统栏背景,
我们把它设成false,这样当它绘制windowBackground的时候,就会在NavigationBar之上。-->
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowTranslucentStatus">true</item><!--这行代码使布局占据状态栏空间-->
</style>
然后适配一下android8.0【对应api版本27】以上的机型,创建values-27文件夹,然后在该文件夹下创建styles.xml文件
values-27文件夹下styles.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--android9.0启动页全屏适配-->
<style name="SplashTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsTranslucent">false
</item><!--沉浸透明状态栏 可选,窗口是否是半透明,设置状态栏的效果,这个值也会影响状态效果-->
<item name="android:windowDisablePreview">false
</item><!--冷启动是用到的属性,窗口不可见时的预览图,为true时点击app图标会慢一会-->
<item name="android:windowBackground">@drawable/layer_launch2</item><!--替换启动白屏的图片-->
<!-- <item name="android:windowBackground">@mipmap/ic_splash_logo</item>--><!--替换启动白屏的图片-->
<!-- Android P 异性屏适配 可以达到全面屏的效果 -->
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<!-- 在5.0后,增加了一个windowDrawsSystemBarBackgrounds属性,用来标志此窗口是否负责绘制系统栏背景,
我们把它设成false,这样当它绘制windowBackground的时候,就会在NavigationBar之上。-->
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowTranslucentStatus">true</item><!--这行代码使布局占据状态栏空间-->
</style>
</resources>
该文件加了一行代码,对android凹凸屏进行了适配
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
Google对刘海屏的显示方式提供了三种显示模式
// 默认情况,全屏页面不可用刘海区域,非全屏页面可以进行使用
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT = 0;
// 允许页面延伸到刘海区域
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES = 1;
// 不允许使用刘海区域
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER = 2;
在主题中加入android:windowLayoutInDisplayCutoutMode属性指定显示模式
冷启动时为了防止出现白屏或者等待时间,加入了一张默认的图片【也就是启动页的图片】
<item name="android:windowBackground">@drawable/layer_launch2</item><!--替换启动白屏的图片-->
再看看SplashActivity布局文件里,启动页图片的配置
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/layer_launch2"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
可以发现,其实app启动时是有两张图片,一张冷启动时的友好图片,一张是真正的启动页的图片,如果适配的不好的话,冷启动时的背景图就不会和SplashActivity的图片完美重叠,也就是会出现图片压缩或者明显感觉是两张图片放上去的效果。当然,因为我们现在app里面没有加入广告位,所以SplashActivity里面的ImageView用的是默认图,如果用网络请求的广告图,那么就不会有重叠的问题,即使这样,冷启动的图片也要做好全屏适配的效果,回过头来,还是先看目前的问题,图片拉伸的问题
一是要对android P以上的手机进行刘海屏的适配;
二是不要在Activity里对代码进行沉浸式效果的设置;
三在drawable文件夹下,创建图层列表layer-list图片;
layer_launch2.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/white" />
<!--因为使用最长图做适配,所以这里不会有需要填充的地方,所以上面注释掉-->
<item android:bottom="150dp">
<bitmap
android:src="@mipmap/ic_splash_logo" />
</item>
<item android:bottom="30dp">
<bitmap
android:gravity="bottom|center"
android:src="@mipmap/ic_splash_bottom" />
</item>
</layer-list>
对应的效果图如下
可以发现,其实是第一层是白色背景,第二层是上半部分切图,设置了距离底部150dp,150dp是留出来显示底部问题的高度,这个大小可以自己设置,第三层设置的是图片底部居中,然后距离底部30dp,通过三层叠加的效果,实现了最终的效果图,一般的启动页的图片都是通过这种图层列表来实现,这样适配的效果会更好一些
至此,android启动页图片全屏时图片被拉伸问题的问题解决掉啦!
4、总结
作为一名有职业道德的程序员,对于代码中的瑕疵还是要解决的,特别是对于启动页这种“门面”,启动页的代码处理逻辑其实就这几个方面:切图尺寸选择、主题文件配置【刘海屏适配】、drawable文件创建及处理、、沉浸式效果处理。