Android:启动页--最佳实践

一、前言

Android 开发过程中启动页是必不可少的,但是我们经常会看到启动打开后是先白屏或者黑屏,然后才会显示出启动页的图片,本文会解析此现象的原因,以及给出解决方案

1.1 启动白屏或黑屏的原因

AndroidManifest.xml中的application标签中设置了theme,当设置的theme是Light类型时启动白屏,当设置theme是Dark类型时启动黑屏

1.2 进一步分析

当系统启动一个app时,zygote进程会fork一个app子进程,进程创建后在启动activity时就会创建一个window,这个window会使用theme中设置的windowBackground来显示背景颜色或者图片,当使用LightDark时跟进代码就能看到默认设置的windowBackground就是白色和黑色。

二、启动页--常规做法

2.1 创建Activity:SplashActivity

class SplashActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)
        Handler().postDelayed({
            startActivity(Intent(this,MainActivity::class.java))
            finish()
        },3000)
    }
}

2.2 给启动页创建background:splash_background.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white"/>
    <item>
        <bitmap android:gravity="center"
                android:src="@drawable/splash_screen"/>
    </item>
</layer-list>

下面重点说下bitmap的属性功能:

  • android:antialias

    布尔值。启用或停用抗锯齿。

  • android:dither

    布尔值。当位图的像素配置与屏幕不同时(例如:ARGB 8888 位图和 RGB 565 屏幕),启用或停用位图抖动。

  • android:filter

    布尔值。启用或停用位图过滤。当位图收缩或拉伸以使其外观平滑时使用过滤。

  • android:gravity

    定义位图的重力。重力指示当位图小于容器时,可绘制对象在其容器中放置的位置。

    必须是以下一个或多个(用 '|' 分隔)常量值:

    说明
    top 将对象放在其容器顶部,不改变其大小。
    bottom 将对象放在其容器底部,不改变其大小。
    left 将对象放在其容器左边缘,不改变其大小。
    right 将对象放在其容器右边缘,不改变其大小。
    center_vertical 将对象放在其容器的垂直中心,不改变其大小。
    fill_vertical 按需要扩展对象的垂直大小,使其完全适应其容器。
    center_horizontal 将对象放在其容器的水平中心,不改变其大小。
    fill_horizontal 按需要扩展对象的水平大小,使其完全适应其容器。
    center 将对象放在其容器的水平和垂直轴中心,不改变其大小。
    fill 按需要扩展对象的垂直大小,使其完全适应其容器。这是默认值。
    clip_vertical 可设置为让子元素的上边缘和/或下边缘裁剪至其容器边界的附加选项。裁剪基于垂直重力:顶部重力裁剪上边缘,底部重力裁剪下边缘,任一重力不会同时裁剪两边。
    clip_horizontal 可设置为让子元素的左边和/或右边裁剪至其容器边界的附加选项。裁剪基于水平重力:左边重力裁剪右边缘,右边重力裁剪左边缘,任一重力不会同时裁剪两边。
  • android:mipMap

    布尔值。启用或停用 mipmap 提示。如需了解详细信息,请参阅 setHasMipMap()。默认值为 false。

  • android:tileMode

    定义平铺模式。当平铺模式启用时,位图会重复。重力在平铺模式启用时将被忽略。

    必须是以下常量值之一:

    说明
    disabled 不平铺位图。这是默认值。
    clamp 当着色器绘制范围超出其原边界时复制边缘颜色
    repeat 水平和垂直重复着色器的图像。
    mirror 水平和垂直重复着色器的图像,交替镜像图像以使相邻图像始终相接。

2.3 给启动页创建style:SplashTheme

<style name="SplashTheme" parent="AppTheme">
  <item name="windowNoTitle">true</item><!--无标题-->
  <item name="android:windowFullscreen">true</item><!--全屏-->
  <item name="android:windowIsTranslucent">true</item><!--半透明-->
  <item name="android:windowBackground">@drawable/splash_background</item>
</style>

2.4 在AndroidManifest.xml中给SplashActivity设置style

<activity android:name=".SplashActivity"
          android:theme="@style/SplashTheme">
  <intent-filter>
    <action android:name="android.intent.action.MAIN"/>

    <category android:name="android.intent.category.LAUNCHER"/>
  </intent-filter>
</activity>

通过上面的4步设置就能够解决打开app白屏或黑屏的问题了。

三、最佳实践

3.1 场景1:只有屏幕中间有一张图片或者是图片+文字

通过上面的方式就能实现,注意bitmap使用gravitycenter让图片和文字居中显示

3.2 场景2:屏幕中部和底部都有图片或者文字

这种上下布局的,例如微博,可以把图片切成上下两个,或者切割图片上下左右使图片整体能够居中显示

方式一:将图片切成屏幕中央显示的图片和底部图片

splash_background.xml中就需要换种写法了

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 整体的背景颜色 -->
    <item>
        <color android:color="@color/white"/>
    </item>
    <!-- 顶部 -->
    <item>
        <bitmap android:gravity="center"
                android:src="@drawable/splash_center"/>
    </item>
    <!-- 底部 -->
    <item>
        <bitmap android:gravity="bottom|center_horizontal"
                android:src="@drawable/splash_bottom"/>
    </item>
</layer-list>

当手机底部虚拟导航栏时,底部图片会被遮挡,使导航栏透明即可:

class SplashActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)
        Handler().postDelayed({
            startActivity(Intent(this,MainActivity::class.java))
            finish()
        },3000)
    }
}

这句window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)是关键

方式二:将图片设置成background而不是windowBackground

  • style设置:
<style name="SplashTheme" parent="AppTheme">
  <item name="windowNoTitle">true</item>
  <item name="android:windowFullscreen">true</item>
  <item name="android:windowIsTranslucent">true</item>
  <item name="android:windowBackground">@android:color/white</item>
  <item name="android:background">@drawable/splash_background</item>
</style>

用background来设置背景图片

  • splash_background.xml设置:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white"/>
    <item>
        <bitmap android:gravity="clip_vertical|clip_horizontal"
                android:src="@drawable/splash_screen"/>
    </item>
</layer-list>

利用bitmap的gravity属性,用clip_vertical|clip_horizontal来裁剪图片

注意:利用第二种方式时不能使用window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION),这个会导致图片被拉伸

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容

  • XML bitmap XML 位图是在 XML 中定义的资源,指向位图文件。实际上是原始位图文件的别名。XML 可...
    李建彪阅读 1,711评论 0 3
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,089评论 1 32
  • Drawable Resource也即可绘制对象资源,是指可在屏幕上绘制的图形,以及可以使用getDrawable...
    zivxia阅读 745评论 0 1
  • 一、CSS入门 1、css选择器 选择器的作用是“用于确定(选定)要进行样式设定的标签(元素)”。 有若干种形式的...
    宠辱不惊丶岁月静好阅读 1,584评论 0 6
  • 选择qi:是表达式 标签选择器 类选择器 属性选择器 继承属性: color,font,text-align,li...
    love2013阅读 2,303评论 0 11