Android启动页解决攻略最终版

相信很多人都在网上查过关于启动白屏或者黑屏的问题。

一般的App应该是分为两种:

  • 有闪屏页或者启动页(SplashActivity),页面大概会持续2到3秒
  • 没有闪屏页和启动页,打开应用后会直接跳转到应用主界面

不管有没有启动页,如果你不处理,你会发现当你点击桌面上那个icon图标的时候会先闪白屏或者黑屏一下,然后才会进入我们设定的页面。

但是我们手机上的常用应用,比如美团,今日头条,微信等,点击app icon的时候,其实感觉是一瞬间秒开的,没有白屏的过程,那么这是如何处理的呢?

先说一说为什么会出现白屏或者黑屏吧!

当打开一个Activity时,如果这个Activity所属的应用还没有在运行,系统会为这个Activity所属的应用创建一个进程,但进程的创建与初始化都需要时间,如果没有任何反应的话,如果程序初始化的时间很长,用户可能还以为没有点到相应的位置。但此时所启动的程序还没初始化完,既无法显示程序,又不能停在原处不做任何动作,这就有了Starting Window的概念,也可以称之为Preview Window。

Starting Window就是一个用于在应用程序进程创建并初始化成功前显示的临时窗口,拥有的Window Type是TYPE_APPLICATION_STARTING。在程序初始化完成前显示这个窗口,以告知用户系统已经知道了他要打开这个应用并做出了响应,当程序初始化完成后显示用户UI并移除这个窗口。

显示白屏或者黑屏,是由你的启动Activity或者Application来决定的。如果你使用的是Light主题,那么就可能出现白屏;如果你使用的是Black主题,那么就可能出现黑屏。当你设置Light或者Black主题时,Starting Window显示的就是你启动Activity的android:windowBackground属性,所以才会出现白屏或者黑屏的情况。

网上有很多教程,说是把主题的背景设为透明,这样子的确实没有白屏了,但是你会发现点击完app的icon之后,会有一小会的停顿,给用户一种卡顿的感觉,体验非常不好,不能为了实现功能而实现功能,软件开发用户体验至上!


那么好的体验该如何开发呢?我们以实现一个今日头条app的启动页作为案例。

我们先来看一看常规情况下app启动的黑白屏。

为了让白屏或者黑屏明显的显示,在SplashActivity的onCreate方法中setContentView之前加入一个休眠1秒的操作。

/*还没有加载布局是睡眠1秒,确保黑屏或白屏效果明显*/
try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
/**闪屏页持续1s然后进入主页*/
mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(activity,AdsActivity.class);
                startActivity(intent);
                finish();
                overridePendingTransition(R.anim.fade,R.anim.hold);
            }
        }, 1000);

效果是:

没做任何处理的启动页

接下来我们来消灭白屏。

第一步 消灭白屏

1.我们需要删除原来的闪屏页的布局activity_splash.xml,同时删除SplashActivity中setContentView(R.layout.activity_splash)方法。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    /*还没有加载布局是睡眠1秒,确保黑屏或白屏效果明显*/
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

//    setContentView(R.layout.activity_splash);

}

2.为了让闪屏页持续时间长一点,我们用handler模拟耗时操作,1秒后进行跳转。

mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
        //这块耗时操作可以进行初始化,或者网络请求等,1秒结束后跳转到广告页面
            Intent intent = new Intent(activity,AdsActivity.class);
            startActivity(intent);
            finish();
        }
    }, 1000);

3.我们删除了闪屏页的布局文件,想法是将闪屏的背景作为Activity的主题背景,要做到这一点,首先要在 res/drawable创建一个XML drawable文件。

<?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="20dp">
        <bitmap
            android:gravity="bottom"
            android:src="@mipmap/icon_logo" />
    </item>

</layer-list>

4.接下来在style.xml中创建一个闪屏页的主题,将创建的xml设置为window的背景。并且在AndroidManifest.xml中给SplashActivity配置style。

<style name="AppTheme.Splash" parent ="android:Theme.Holo.Light.NoActionBar">
    <item name="android:windowBackground">@drawable/drawable_splash</item>
</style>
<activity android:name=".SplahActivity"
       android:theme="@style/AppTheme.Splash">
       <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

这个时候运行程序,我们发现其实已经没有白屏了。

第二步,我们实现广告加载页面

** 1.广告页是一个倒计时的显示,布局中放入一个TextView来显示倒计时信息,放入一个ImageView来显示加载动画。点击跳过广告的时候显示加载动画。**

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/iv_logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/icon_logo"
        android:layout_marginBottom="20dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"/>

    <RelativeLayout
        android:layout_marginBottom="20dp"
        android:layout_above="@+id/iv_logo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent">
        
        <TextView
            android:id="@+id/tv_ads"
            android:layout_alignParentRight="true"
            android:layout_marginTop="20dp"
            android:layout_marginRight="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="跳过广告"
            android:textColor="@color/white"
            android:textSize="12sp"
            android:background="@drawable/bg_ad_text"
            android:padding="5dp"/>

    </RelativeLayout>

</RelativeLayout>

2.页面实现中,我们定义一个CountDownTimer,这个类是Android SDK提供用来进行倒计时的。CountDownTimer(long millisInFuture, long countDownInterval)有两个参数,第一个是计时的总时长,第二个是间隔。

public class AdsActivity extends Activity {
    private Activity activity;
    private TextView tvAds;
    private CountDownTimer countDownTimer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ads);
        activity =this;
        tvAds = (TextView) findViewById(R.id.tv_ads);

        countDownTimer = new CountDownTimer(4000,1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                tvAds.setText("跳过广告"+(millisUntilFinished/1000)+"秒");
            }

            @Override
            public void onFinish() {
                Intent intent = new Intent(activity,MainActivity.class);
                startActivity(intent);
                finish();
            }
        }.start();

        /**
         * 跳过广告
         */
        tvAds.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                countDownTimer.cancel();
                Intent intent = new Intent(activity,MainActivity.class);
                startActivity(intent);
                finish();
            }
        });
    }
}

第三步,优化

1.我们运行起来,发现页面之间的跳转有些不美观,从右向左进入的动画感觉有些生硬。因此我们给页面之间加入转场动画。

#fade.xml 页面退出动画
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
       android:interpolator="@android:anim/accelerate_interpolator"
       android:fromAlpha="0.0" android:toAlpha="0.0"
       android:duration="400" />
#hold.xml 页面进入动画
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
       android:interpolator="@android:anim/accelerate_interpolator"
       android:fromXDelta="0" android:toXDelta="0"
       android:duration="400" />

在每个Intent跳转的地方加入转场效果

Intent intent = new Intent(activity,AdsActivity.class);
startActivity(intent);
finish();
overridePendingTransition(R.anim.fade,R.anim.hold);

最终的效果是:

消除黑白屏的启动页

有两点注意:

  • overridePendingTransition方法要写在finish后面
  • overridePendingTransition方法一定要写在主线程中,在子线程是没有作用的。

源码地址:http://download.csdn.net/download/u012771445/9971093

本文作者: shijiacheng
本文链接:http://shijiacheng.studio/2017/09/09/android-splash-demo/
版权声明:本博客所有文章除特别声明外,均为原创文章。请尊重劳动成果,转载注明出处!
转载请注明:转自http://shijiacheng.studio

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,834评论 25 707
  • 很多时候,我们启动APP时会有短暂的白屏或者黑屏,大概1~2秒后,才会显示主界面或者显示启动页,这是为什么呢?本篇...
    sendtion阅读 17,450评论 16 95
  • 前言 相信做过Android的朋友都知道,当一个APP启动时,界面会首先展示一个白屏或者黑屏,然后再进入欢迎页,稍...
    拉丁吴阅读 17,916评论 32 100
  • 在网上搜索了许多关于app启动白屏的文章大致分为两类 第一种是在style的app的theme 里设置 true ...
    licue阅读 5,701评论 0 0
  • 如果一个人开始驻足你的生命,慢慢成为一道风景,也许你看不到的有那么多,那么你也许唯一能够做的事情是等一个答案,等那...
    Eskmous阅读 387评论 0 1