如何制作启动画面?


548

我想让我的应用看起来更专业,所以我决定要制作一个初始屏幕。

我将如何创建然后实施它?


58
为什么使用启动画面看起来应用程序更专业?我知道没有一个“专业”的Android应用程序。
theomega 2011年

7
同意@theomega。启动画面只是令人讨厌。
马特·鲍尔

85
仅当需要执行后台加载工作时,才应显示启动屏幕。否则,当您尽快向用户提供他们想要的应用程序给您的应用程序时,您的应用程序看起来更“专业”。用户注意到(并被它所困扰)超过100ms的延迟,并且通过添加启动画面,您比此阈值高一个数量级。
CodeFusionMobile 2011年

74
kindle应用程序,aldiko(阅读器),海豚..嗯,OS :)他们全都受到了欢迎。Opera Mobile,Mantan Reader,地图。我可以继续。如果它隐藏了负载,则至少让用户知道您的应用已启动。当屏幕上至少有人时,隐藏几秒钟的延迟会更好。
baash05 '02

9
启动画面为您提供了绝佳的机会来宣传您的游戏或应用程序公司名称或徽标。我喜欢使启动屏幕可点击,因此用户可以选择跳到游戏上。如果用户每次打开您的应用程序时总是看到您公司徽标的半秒钟,那么他们将更有可能记住您的身份。只要确保他们在您的应用程序上拥有良好的体验即可。
2015年

Answers:


509

进一步阅读:

旧答案:

如何简单的启动画面

此答案显示了在您的应用程序启动时(例如出于品牌原因)如何在固定的时间内显示启动屏幕。例如,您可能选择显示启动屏幕3秒钟。但是,如果要显示可变时间的垃圾邮件屏幕(例如,应用程序启动时间),则应查看Abdullah的回答https://stackoverflow.com/a/15832037/401025。但是请注意,应用程序在新设备上的启动速度可能非常快,因此用户只会看到闪光,这是不良的UX。

首先,您需要在layout.xml文件中定义垃圾邮件屏幕

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

          <ImageView android:id="@+id/splashscreen" android:layout_width="wrap_content"
                  android:layout_height="fill_parent"
                  android:src="@drawable/splash"
                  android:layout_gravity="center"/>

          <TextView android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text="Hello World, splash"/>

  </LinearLayout>

您的活动:

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;

public class Splash extends Activity {

    /** Duration of wait **/
    private final int SPLASH_DISPLAY_LENGTH = 1000;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.splashscreen);

        /* New Handler to start the Menu-Activity 
         * and close this Splash-Screen after some seconds.*/
        new Handler().postDelayed(new Runnable(){
            @Override
            public void run() {
                /* Create an Intent that will start the Menu-Activity. */
                Intent mainIntent = new Intent(Splash.this,Menu.class);
                Splash.this.startActivity(mainIntent);
                Splash.this.finish();
            }
        }, SPLASH_DISPLAY_LENGTH);
    }
}

就这样 ;)


3
@ user2606414请针对您的问题创建一个问题,然后粘贴整个错误日志。
投票

39
别忘了在清单中添加醒目内容
Jawad Zeb 2014年

8
@Peter的问题不是在加载数据时如何显示启动屏幕。
2014年

18
对于启动屏幕来说,这不是一个合适的解决方案,它会使用户等待显示启动屏幕,但是启动屏幕的目的反之亦然。用户正在等待时,它应该显示启动屏幕。请参阅@Abdullah的解决方案。
efeyc

4
而不是让应用程序停滞不前SPLASH_DISPLAY_LENGTH。您应该改为这样做:bignerdranch.com/blog/splash-screens-the-right-way
miguel.martin

594

请注意,此解决方案不会让用户等待更多:启动屏幕的延迟取决于应用程序的启动时间。

当您打开任何android应用程序时,默认情况下都会出现一些黑屏,其顶部和应用程序的图标位于顶部,您可以使用样式/主题来对其进行更改。

首先,在values文件夹中创建一个style.xml并为其添加样式。

<style name="splashScreenTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">
    <item name="android:windowBackground">@drawable/splash_screen</item>
</style>

除了使用之外,@android:style/Theme.DeviceDefault.Light.NoActionBar您还可以将任何其他主题用作父主题。

其次,在您的应用程序Manifest.xml中添加android:theme="@style/splashScreenTheme"到您的主要活动中。

<activity
        android:name="MainActivity"
        android:label="@string/app_name"
        android:theme="@style/splashScreenTheme" >

第三,在onCreate()启动活动中更新主题。

protected void onCreate(Bundle savedInstanceState) {
    // Make sure this is before calling super.onCreate
    setTheme(R.style.mainAppTheme);
    super.onCreate(savedInstanceState);
}

更新 查看此帖子

感谢@ mat1h和@adelriosantiago


3
看来“父级”仅在API 14及更高版本中受支持
user1832478 2014年

103
这是制作启动画面的正确方法。谢谢!拖延投票获得更多投票的答案只是一个坏习惯。任何事情都不应延迟用户看到第一个功能屏幕。
dineth 2014年

7
我对此遇到的一个问题是<item name="android:background">将覆盖windowBackground。如果没有android:background定义,我的任何片段背景都是透明的,从而揭示了前景内容背后的活动。
威廉·格兰德

4
@阿卜杜拉:我按照你说的去做。它工作正常,但是在活动转换时启动屏幕会显示几毫秒。
nizam.sp 2015年

3
@阿卜杜拉谢谢!那将是一个可能的解决方案,但是我发现了这一点:plus.google.com/+AndroidDevelopers/posts/Z1Wwainpjhd,为避免为每个屏幕尺寸创建不同的图像,还可以创建一个包含该图像的XML以使其看起来像在所有屏幕上都可以。
adelriosantiago

52
  • 创建活动:飞溅
  • 创建布局XML文件:splash.xml
  • 将UI组件放在splash.xml布局中,这样看起来就可以了
  • 您的Splash.java可能如下所示:

    public class Splash extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.splash);
    
            int secondsDelayed = 1;
            new Handler().postDelayed(new Runnable() {
                    public void run() {
                            startActivity(new Intent(Splash.this, ActivityB.class));
                            finish();
                    }
            }, secondsDelayed * 1000);
        }
    }
  • 更改ActivityB.class为初始屏幕后要开始的任何活动

  • 检查清单文件,它应该看起来像

        <activity
            android:name=".HomeScreen"
            android:label="@string/app_name">     
        </activity>

        <activity
            android:name=".Splash"
            android:label="@string/title_activity_splash_screen">     
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

28
这不是启动画面的目的。这将导致额外的1秒延迟。启动画面应该是加载应用程序的第一个画面时的图像。此链接可能会有所帮助。stackoverflow.com/a/7057332/869451
efeyc 2011年

2
@efeyc:您是100%正确的..但是,当应用启动时,它看起来非常不错..您不觉得吗?
McLan

1
@ Suda.nese绝对不是。用户不想看图片,用户想使用该应用程序并且没有不必要的延迟
Tim

1
@TimCastelijns这取决于正在开发的应用程序,初始屏幕是什么样子..当然,这意味着实用,但是谁说它不能另外使用!
McLan 2015年

6
同意@ Suda.nese如果应用程序要求包括启动画面,则不是启动画面!当然,这对于用户而言可能不是理想的选择,但是如果客户想要启动画面,那么请天真地将其提供给他们
james 2015年

29

上面的答案很好,但我想补充一下。我是Android新手,在开发过程中遇到了这些问题。希望这可以帮助像我这样的人。

  1. “启动”屏幕是我的应用程序的入口,因此请在AndroidManifest.xml中添加以下几行。

        <activity
            android:name=".SplashActivity"
            android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
  2. 初始屏幕在应用程序生命周期中仅应显示一次,我使用布尔变量记录初始屏幕的状态,并且仅在第一次显示。

    public class SplashActivity extends Activity {
        private static boolean splashLoaded = false;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            if (!splashLoaded) {
                setContentView(R.layout.activity_splash);
                int secondsDelayed = 1;
                new Handler().postDelayed(new Runnable() {
                    public void run() {
                        startActivity(new Intent(SplashActivity.this, MainActivity.class));
                        finish();
                    }
                }, secondsDelayed * 500);
    
                splashLoaded = true;
            }
            else {
                Intent goToMainActivity = new Intent(SplashActivity.this, MainActivity.class);
                goToMainActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                startActivity(goToMainActivity);
                finish();
            }
        }
    }

祝您编码愉快!


10
您可以添加android:noHistory="true"AndroidManifest.xml以防止用户回到使用返回按钮的启动画面。
雷切尔(Rachel)

15

阿卜杜拉的答案很好。但是我想在答案中添加更多细节。

实施启动画面

以正确的方式实现启动屏幕与您可能想象的有些不同。您看到的启动视图必须立即准备好,甚至不能在启动活动中为布局文件充气之前。

因此,您将不会使用布局文件。而是将初始屏幕的背景指定为活动的主题背景。为此,首先在res / drawable中创建一个XML drawable。

background_splash.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:drawable="@color/gray"/>

    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher"/>
    </item>

</layer-list>

它只是一个带有中心背景色徽标的图层列表。

现在打开styles.xml并添加此样式

<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/background_splash</item>
</style>

这个主题必须在操作栏上,并带有我们上面刚刚创建的背景。

在清单中,您需要将SplashTheme设置为要用作初始的活动。

<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>

然后,在使用意图进行启动后,在活动代码内将用户导航到特定屏幕。

public class SplashActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    }
}

那是正确的方法。我用这些参考资料来回答。

  1. https://material.google.com/patterns/launch-screens.html
  2. https://www.bignerdranch.com/blog/splash-screens-the-right-way/ 感谢这些家伙将我推向正确的方向。我想帮助其他人,因为不建议您接受接受的答案来启动屏幕。

1
我看到了YouTube有关此的教程。但我认为位图大小将成为问题,因为您无法使用来调整其大小layer-list
RoCk RoCk

14
  1. 创建一个 Activity SplashScreen.java

    public class SplashScreen extends Activity {
    protected boolean _active = true;
    protected int _splashTime = 3000; // time to display the splash screen in ms
    
    
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splashscreen);
    
        Thread splashTread = new Thread() {
            @Override
            public void run() {
                try {
                    int waited = 0;
                    while (_active && (waited < _splashTime)) {
                        sleep(100);
                        if (_active) {
                            waited += 100;
                        }
                    }
                } catch (Exception e) {
    
                } finally {
    
                    startActivity(new Intent(SplashScreen.this,
                            MainActivity.class));
                    finish();
                }
            };
                 };
        splashTread.start();
    }
     }
  2. splashscreen.xml 会像这样

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="600px" android:layout_height="1024px"
      android:background="#FF0000">
    </RelativeLayout> 

13

默认情况下,Splash Screnn不会自动使您的应用程序看起来更专业。专业设计的启动画面可以使您的应用程序看起来更专业,但是如果您不知道如何编写,则其余应用程序实际上将是多么专业。

拥有启动画面的唯一原因(借口)是因为您正在执行大量计算或正在等待GPS / WiFi启动,因为您的应用程序依赖于启动之前。如果没有这些计算的结果或无法使用GPS / WiFi(等等),您的应用程序就会死在水中,因此您会觉得您需要启动屏幕,并且必须阻止任何其他正在运行的程序(包括背景程序)的屏幕视图)。

这样的启动画面应看起来像您的全屏应用程序,以给人以它已被初始化的印象,然后在完成冗长的计算之后,可以填充最终的详细信息(对图像进行调整)。的机会既然如此或者说,它是唯一的出路程序可以设计的是强大的小

最好允许用户(以及操作系统的其余部分)在等待时执行其他操作,而不是将程序设计为依赖需要一段时间的操作(当等待时间不确定时)。

手机上已经有图标表示GPS / WiFi正在启动。初始屏幕占用的时间或空间可用于加载预计算或实际执行计算。有关您创建的问题以及必须考虑的问题,请参见下面的第一个链接。

如果您绝对必须等待这些计算或GPS / WiFi,则最好只是让应用程序启动,并弹出一个弹出框,指出必须等待这些计算(TEXTUAL“正在初始化”消息是可以的)。可能需要等待GPS / WiFi(如果尚未在其他程序中启用它们),因此无需宣布其等待时间。

请记住,启动屏幕启动时,程序实际上已经在运行,您正在做的就是延迟使用程序,并拖延CPU / GPU来执行大多数不必要的操作。

我们最好真的希望每次启动程序时都等待您看到启动画面,否则我们不会觉得它写的很专业。使“启动画面”为“全屏”并与实际程序的画面重复(因此我们认为实际上它尚未初始化)可以实现您的目标(使您的程序看上去更专业),但我对此不会打赌。

为什么不这样做:http : //cyrilmottier.com/2012/05/03/splash-screens-are-evil-dont-use-them/

怎么做:https//encrypted.google.com/search?q = Android + splash + screen + source

因此,有充分的理由不这样做,但是如果您确定自己的情况超出了这些示例的范围,则上面提供了执行此操作的方法。确保它确实使您的应用程序看起来更专业,或者您已经击败了这样做的唯一理由。

就像YouTube频道一样,每个视频都以冗长的图形简介(和Outro)开头,或者感觉有必要讲个笑话或说明过去一周(不是喜剧或生活风格频道)发生了什么。只是显示节目!(只需运行该程序)。


12

首先,答案确实非常好。但是遇到内存泄漏的问题。此问题在Android社区中通常称为“泄漏活动”。现在那到底是什么意思?

当发生配置更改(例如方向更改)时,Android会销毁Activity并重新创建。通常,垃圾收集器只会清除旧的Activity实例的已分配内存,我们都很好。

“泄漏活动”是指垃圾回收器无法清除旧的Activity实例的已分配内存,因为它being (strong) referenced来自活动了该Activity实例的对象。每个Android应用程序都有为其分配的特定内存量。当垃圾收集器无法释放未使用的内存时,应用程序的性能将逐渐降低,并最终因OutOfMemory错误而崩溃。

如何确定应用程序是否泄漏内存?最快的方法是在Android Studio中打开“内存”标签,并在更改方向时注意分配的内存。如果分配的内存一直在增加而从未减少,那么您将发生内存泄漏。

1.用户更改方向时内存泄漏。 在此处输入图片说明

首先,您需要在布局资源splashscreen.xml文件中定义启动屏幕

启动画面活动的示例代码。

public class Splash extends Activity {
 // 1. Create a static nested class that extends Runnable to start the main Activity
    private static class StartMainActivityRunnable implements Runnable {
        // 2. Make sure we keep the source Activity as a WeakReference (more on that later)
        private WeakReference mActivity;

        private StartMainActivityRunnable(Activity activity) {
         mActivity = new WeakReference(activity);
        }

        @Override
        public void run() {
         // 3. Check that the reference is valid and execute the code
            if (mActivity.get() != null) {
             Activity activity = mActivity.get();
             Intent mainIntent = new Intent(activity, MainActivity.class);
             activity.startActivity(mainIntent);
             activity.finish();
            }
        }
    }

    /** Duration of wait **/
    private final int SPLASH_DISPLAY_LENGTH = 1000;

    // 4. Declare the Handler as a member variable
    private Handler mHandler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(icicle);
        setContentView(R.layout.splashscreen);

        // 5. Pass a new instance of StartMainActivityRunnable with reference to 'this'.
        mHandler.postDelayed(new StartMainActivityRunnable(this), SPLASH_DISPLAY_LENGTH);
    }

    // 6. Override onDestroy()
    @Override
    public void onDestroy() {
     // 7. Remove any delayed Runnable(s) and prevent them from executing.
     mHandler.removeCallbacksAndMessages(null);

     // 8. Eagerly clear mHandler allocated memory
     mHandler = null;
    }
}

有关更多信息,请通过此链接


7

不必要的在4到5的“在启动画面上停止”没有多大意义。可以,如果您在后台加载某些东西,也可以按照以下方法来实现启动屏幕:- 正确地实现启动屏幕与您想象的有些不同。您看到的启动视图必须立即准备就绪,甚至不能在启动活动中为布局文件充气之前。

因此,您将不会使用布局文件。而是将初始屏幕的背景指定为活动的主题背景。为此,首先,在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/gray"/>

    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher"/>
    </item>

</layer-list>

在这里,我设置了背景色和图像。

接下来,将其设置为主题中启动活动的背景。导航到您的styles.xml文件,并为您的启动活动添加新主题:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

    <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/background_splash</item>
    </style>

</resources>

在新的SplashTheme中,将window背景属性设置为XML drawable。在AndroidManifest.xml中将其配置为启动活动的主题:

<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>

最后,SplashActivity类应将您转发至主要活动:

     public class SplashActivity extends AppCompatActivity {

             @Override
             protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);

               Intent intent = new Intent(this, MainActivity.class);
               startActivity(intent);
               finish();
    }
}

更多详细信息请阅读:1. https://www.bignerdranch.com/blog/splash-screens-the-right-way/ 2. 2. http://blog.goodbarber.com/3-tips-to-create-a -great-splash-screen-for-your-mobile-app_a287.html


4

这是完整的代码

SplashActivity.java

public class SplashActivity extends AppCompatActivity {

private final int SPLASH_DISPLAY_DURATION = 1000;

@Override
public void onCreate(Bundle bundle) {
    super.onCreate(bundle);


    new Handler().postDelayed(new Runnable(){
        @Override
        public void run() {

            Intent mainIntent = new Intent(SplashActivity.this,MainActivity.class);
            SplashActivity.this.startActivity(mainIntent);
            SplashActivity.this.finish();
        }
    }, SPLASH_DISPLAY_DURATION);
}}

在可绘制对象中创建此bg_splash.xml

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item
    android:drawable="@color/app_color"/>

<item>
    <bitmap
        android:gravity="center"
        android:src="@drawable/ic_in_app_logo_big"/>
</item></layer-list>

styles.xml中创建一个自定义主题

<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowBackground">@drawable/bg_splash</item>
</style>

最后在AndroidManifest.xml中为您的活动指定主题

<activity
        android:name=".activities.SplashActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:theme="@style/SplashTheme">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

干杯。


我将如何添加xml文件而不是drawable
viper

我的意思是您必须如上所述在drawable目录中创建bg_splash.xml。
awsleiman

4

初始屏幕不应从布局文件加载,加载时可能仍然有些滞后。

最好的方法是只为您的SplashScreenActivity创建一个主题,并将其设置the android:windowBackground为可绘制的资源。

https://www.bignerdranch.com/blog/splash-screens-the-right-way/

简而言之:

在清单中声明您的SplashScreenActivity:

<activity
        android:name=".activities.SplashScreenActivity"
        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>

在您的SplashScreenActivity.java中:

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = new Intent(this, MainActivity_.class);
    startActivity(intent);
    finish();

}

接下来,为主题的背景窗口创建资源:

<style name="SplashTheme" parent="Theme.Bumpfie.Base">
    <item name="android:windowBackground">@drawable/splash</item>
</style>

可绘制文件splash.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/app_logo"/>
    </item>
</layer-list>

4

在Android Marshmallow之后,我想到的其他可用于启动画面的生产性用途都要求Android Permissions在您的应用程序的启动画面中使用。

似乎大多数应用都是以这种方式处理权限请求。

  • 对话框使UIX变得很糟糕,它们破坏了主流程,使您决定运行时,事实是,大多数用户甚至都不在乎您的应用是否要在SD卡上写东西。他们中的某些人甚至可能不理解我们要传达的内容,除非我们将其翻译成简明的英语。

  • 一次请求权限可以减少每次操作之前的“ if else”数量,并使您的代码看起来很整洁。

这是一个示例,说明如何在运行Android OS 23+的设备的启动活动中请求权限。

如果已授予所有权限或已经授予所有权限,或者应用程序已在Pre Marshmallow上运行,则只需半秒钟即可显示主要内容,以便用户能欣赏我们在阅读此问题并尽力而为时所付出的努力。

import android.Manifest;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import com.c2h5oh.beer.R;
import com.c2h5oh.beer.utils.Animatrix;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SplashActivity extends AppCompatActivity {

    final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);

        //show animations 
        Animatrix.scale(findViewById(R.id.title_play), 100);
        Animatrix.scale(findViewById(R.id.title_edit), 100);
        Animatrix.scale(findViewById(R.id.title_record), 100);
        Animatrix.scale(findViewById(R.id.title_share), 100);

        if (Build.VERSION.SDK_INT >= 23) {

            // Marshmallow+ Permission APIs
            fuckMarshMallow();

        } else {

            // Pre-Marshmallow
            ///Display main contents
            displaySplashScreen();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
                Map<String, Integer> perms = new HashMap<String, Integer>();
                // Initial
                perms.put(Manifest.permission.READ_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.RECORD_AUDIO, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.MODIFY_AUDIO_SETTINGS, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.VIBRATE, PackageManager.PERMISSION_GRANTED);
                // Fill with results
                for (int i = 0; i < permissions.length; i++)
                    perms.put(permissions[i], grantResults[i]);

                // Check for ACCESS_FINE_LOCATION
                if (perms.get(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.MODIFY_AUDIO_SETTINGS) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.VIBRATE) == PackageManager.PERMISSION_GRANTED) {
                    // All Permissions Granted

                    // Permission Denied
                    Toast.makeText(SplashActivity.this, "All Permission GRANTED !! Thank You :)", Toast.LENGTH_SHORT)
                            .show();

                    displaySplashScreen();

                } else {
                    // Permission Denied
                    Toast.makeText(SplashActivity.this, "One or More Permissions are DENIED Exiting App :(", Toast.LENGTH_SHORT)
                            .show();

                    finish();
                }
            }
            break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }


    @TargetApi(Build.VERSION_CODES.M)
    private void fuckMarshMallow() {
        List<String> permissionsNeeded = new ArrayList<String>();

        final List<String> permissionsList = new ArrayList<String>();
        if (!addPermission(permissionsList, Manifest.permission.READ_EXTERNAL_STORAGE))
            permissionsNeeded.add("Read SD Card");
        if (!addPermission(permissionsList, Manifest.permission.RECORD_AUDIO))
            permissionsNeeded.add("Record Audio");
        if (!addPermission(permissionsList, Manifest.permission.MODIFY_AUDIO_SETTINGS))
            permissionsNeeded.add("Equilizer");
        if (!addPermission(permissionsList, Manifest.permission.VIBRATE))
            permissionsNeeded.add("Vibrate");

        if (permissionsList.size() > 0) {
            if (permissionsNeeded.size() > 0) {

                // Need Rationale
                String message = "App need access to " + permissionsNeeded.get(0);

                for (int i = 1; i < permissionsNeeded.size(); i++)
                    message = message + ", " + permissionsNeeded.get(i);

                showMessageOKCancel(message,
                        new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                        REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                            }
                        });
                return;
            }
            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
            return;
        }

        Toast.makeText(SplashActivity.this, "No new Permission Required- Launching App .You are Awesome!!", Toast.LENGTH_SHORT)
                .show();

        displaySplashScreen();
    }


    private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
        new AlertDialog.Builder(SplashActivity.this)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", null)
                .create()
                .show();
    }

    @TargetApi(Build.VERSION_CODES.M)
    private boolean addPermission(List<String> permissionsList, String permission) {

        if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
            permissionsList.add(permission);
            // Check for Rationale Option
            if (!shouldShowRequestPermissionRationale(permission))
                return false;
        }
        return true;
    }

    /**
     * Display main content with little delay just so that user can see
     * efforts I put to make this page
     */
    private void displaySplashScreen() {
        new Handler().postDelayed(new Runnable() {

        /*
         * Showing splash screen with a timer. This will be useful when you
         * want to show case your app logo / company
         */

            @Override
            public void run() {
                startActivity(new Intent(SplashActivity.this, AudioPlayerActivity.class));
                finish();
            }
        }, 500);
    }


}

4

您将不会使用布局文件。而是将初始屏幕的背景指定为活动的主题背景。为此,首先在res / drawable中创建一个XML drawable。

注意:以下所有代码均可用GitHub链接

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:drawable="@color/gray"/>

    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher"/>
    </item>

</layer-list>

在这里,我设置了背景色和图像。

接下来,将其设置为主题中启动活动的背景。导航到您的styles.xml文件,并为您的启动活动添加新主题:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

    <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/background_splash</item>
    </style>

</resources>

在新的SplashTheme中,将window背景属性设置为XML drawable。在AndroidManifest.xml中将其配置为启动活动的主题:

<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>

最后,您的SplashActivity类应将您转发至主要活动:

public class SplashActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    }
}

请注意,您甚至没有为此SplashActivity设置视图。视图来自主题。在主题中为启动活动设置UI时,将立即可用。

如果您确实有一个用于启动活动的布局文件,则只有在您的应用程序完全初始化之后,该布局文件才对用户可见,为时已晚。您希望仅在初始化应用程序之前的短时间内显示启动画面。


3
public class MainActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Thread t=new Thread()
    {

        public void run()
        {   

            try {

                sleep(2000);
                finish();
                Intent cv=new Intent(MainActivity.this,HomeScreen.class/*otherclass*/);
                startActivity(cv);
            } 

            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    t.start();
}

2

创建一个Activity,让我们的Activity名为“ A”,然后创建一个名为myscreen.xml的xml文件,在其中将初始屏幕图像设置为背景,然后使用倒数计时器从一个Activtity导航到另一个Activtity。要知道如何使用倒数计时器,请参阅我在这个问题中的答案Android中的TimerTask?


2

启动画面示例:

public class MainActivity extends Activity {
    private ImageView splashImageView;
    boolean splashloading = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        splashImageView = new ImageView(this);
        splashImageView.setScaleType(ScaleType.FIT_XY);
        splashImageView.setImageResource(R.drawable.ic_launcher);
        setContentView(splashImageView);
        splashloading = true;
        Handler h = new Handler();
        h.postDelayed(new Runnable() {
            public void run() {
                splashloading = false;
                setContentView(R.layout.activity_main);
            }

        }, 3000);

    }

}

2

启动画面是Android中一个有点用处的对象:不能尽快加载它以隐藏主要活动启动的延迟。使用它的原因有两个:广告和网络运营。

作为对话框的实现,可以从初始屏幕立即跳转到活动的主界面。

public class SplashDialog extends Dialog {
    ImageView splashscreen;
    SplashLoader loader;
    int splashTime = 4000;

    public SplashDialog(Context context, int theme) {
        super(context, theme);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
        setCancelable(false);

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                cancel();
            }
        }, splashTime);

    }
}

布局:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/white">

    <ImageView
        android:id="@+id/splashscreen"
        android:layout_width="190dp"
        android:layout_height="190dp"
        android:background="@drawable/whistle"
        android:layout_centerInParent="true" />

</RelativeLayout>

并开始:

public class MyActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getIntent().getCategories() != null &&  getIntent().getCategories().contains("android.intent.category.LAUNCHER")) {
            showSplashScreen();
        }
    }

    protected Dialog splashDialog;
    protected void showSplashScreen() {
        splashDialog = new SplashDialog(this, R.style.SplashScreen);
        splashDialog.show();
    }

    ...
}

这种方法有一个好处,那就是您可以直接启动MainActivity。例如,当您在应用程序中使用推送通知时,通过单击通知启动应用程序时,可以通过这种方式更好地管理通知目的。
法纳德·托希德卡

2

通过使用CountDownTimer实现另一种方法

@Override
public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.splashscreen);

 new CountDownTimer(5000, 1000) { //5 seconds
      public void onTick(long millisUntilFinished) {
          mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
      }

     public void onFinish() {
          startActivity(new Intent(SplashActivity.this, MainActivity.class));
          finish();
     }

  }.start();
}

2
     - Add in SplashActivity 

   public class SplashActivity extends Activity {

       private ProgressBar progressBar;
       int i=0;
       Context context;
       private GoogleApiClient googleApiClient;

       @Override
       protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_splash);
           context = this;

           new Handler().postDelayed(new Runnable() {
               @Override
               public void run() {
                   startActivity(new Intent(Splash.this, LoginActivity.class));
                   finish();
               }
           }, 2000);

       }

   }

  - Add in activity_splash.xml

   <RelativeLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:tools="http://schemas.android.com/tools"
       xmlns:custom="http://schemas.android.com/apk/res-auto"
       android:background="@color/colorAccent"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       tools:context=".Splash">

       <ImageView
           android:id="@+id/ivLogo"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:src="@mipmap/icon_splash"
           android:layout_centerHorizontal="true"
           android:layout_centerVertical="true"/>


       <ProgressBar
           android:id="@+id/circle_progress"
           style="?android:attr/progressBarStyleHorizontal"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:layout_alignParentBottom="true"
           android:layout_marginBottom="5dp"
           android:max="100"
           android:progressTint="@color/green"
           android:visibility="visible" />

   </RelativeLayout>

  - Add in AndroidManifest.xml

    <activity android:name="ex.com.SplashActivity">
               <intent-filter>
                   <action android:name="android.intent.action.MAIN" />

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

您还可以补充一些解释吗?
罗伯特

是的,请问。您想让我知道什么解释?
Ashish Kumar,

2

真正简单&gr8的方法:

请享用!

这里有足够的答案,将有助于实施。这篇文章旨在帮助其他人创建启动屏幕的第一步!


1

如何在AndroidManifest.xml中定义可以使用相同代码的超灵活启动屏幕,因此无需更改代码。我通常开发代码库,并且不喜欢自定义代码,因为它草率。

<activity
        android:name=".SplashActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <meta-data android:name="launch_class" android:value="com.mypackage.MyFirstActivity" />
        <meta-data android:name="duration" android:value="5000" />
</activity>

然后,SpashActivity本身会查找“ launch_class”的元数据,然后创建Intent本身。元数据“持续时间”定义启动屏幕停留的时间。

public class SplashActivity extends Activity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.activity_splash);

    ComponentName componentName = new ComponentName(this, this.getClass());

    try {
        Bundle bundle = null;
        bundle = getPackageManager().getActivityInfo(componentName, PackageManager.GET_META_DATA).metaData;
        String launch_class = bundle.getString("launch_class");
        //default of 2 seconds, otherwise defined in manifest
        int duration = bundle.getInt("duration", 2000);

        if(launch_class != null) {
            try {
                final Class<?> c = Class.forName(launch_class);

                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Intent intent = new Intent(SplashActivity.this, c);
                        startActivity(intent);
                        finish();
                    }
                }, duration);

            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
  }
}

1

有时,用户打开SplashActivity并立即退出,但该应用仍会在MainActivity之后退出SPLASH_SCREEN_DISPLAY_LENGTH

为了防止它:在进入之前,SplashActivity您应该检查SplashActivity是否完成MainActivity

public class SplashActivity extends Activity {

    private final int SPLASH_SCREEN_DISPLAY_LENGTH = 2000;

    @Override
    public void onCreate(Bundle icicle) {
        ...
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {

                if (!isFinishing()) {//isFinishing(): If the activity is finishing, returns true; else returns false.
                    startActivity(new Intent(SplashActivity.this, MainActivity.class));
                    finish();
                }

            }, SPLASH_SCREEN_DISPLAY_LENGTH);
        }                             
   }                                
}

希望有帮助


1

尽管有很好的答案,但我将展示google推荐的方式:

1)首先创建一个Theme用于启动屏幕:您有一个名为的主题splashscreenTheme,您的启动器主题为:

<style name="splashscreenTheme">
  <item name="android:windowBackground">@drawable/launch_screen</item>
</style>

注意:

android:windowBackground已经设置了初始屏幕图像,无需
再次在UI中执行此操作。

您也可以在这里使用颜色而不是可绘制对象。

2)设置主题为splashscreenActivity的清单

   <activity
            android:name=".activity.splashscreenActivity"
            android:screenOrientation="portrait"
            android:theme="@style/splashscreenTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

3)如果图像不小,请确保launch_screen drawable不在drawable文件夹中。

这将加快启动屏幕的启动速度,并将您从黑屏中拯救出来

这也避免了额外的透支


1

这是我在启动屏幕上看到的最好的帖子:http : //saulmm.github.io/avoding-android-cold-starts

SaúlMolinero为启动屏幕提供了两种不同的选择:利用窗口背景为初始屏幕设置动画,并显示占位符UI(这是Google目前用于其大多数应用程序的一种流行选择)。

每当我需要考虑冷启动时间并避免由于启动时间过长而导致用户流失时,我都会参考这篇文章。

希望这可以帮助!


1

就我而言,我不想创建新的活动仅显示2秒钟的图像。在启动我的MainAvtivity图片时,图像会使用毕加索加载到支架中,我知道加载大约需要1秒钟,因此我决定在MainActivity中执行以下操作OnCreate

splashImage = (ImageView) findViewById(R.id.spllll);

    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

    int secondsDelayed = 1;
    new Handler().postDelayed(new Runnable() {
        public void run() {
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            splashImage.setVisibility(View.GONE);

        }
    }, secondsDelayed * 2000);

启动应用程序时,首先发生的事情是ImageView显示,并通过将窗口标志设置为全屏来删除statusBar。然后,我使用Handler来运行2秒钟,在2秒钟后,我清除了全屏标志并将的可见性设置ImageViewGONE。简单,简单,有效。


1

在android中非常简单,我们只使用处理程序概念来实现启动屏幕

在您的SplashScreenActivity java文件中粘贴以下代码。

在您的SplashScreenActivity xml文件中,使用imageview放置任何图片。

public void LoadScreen() {
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {                 
                Intent i = new Intent(SplashScreenActivity.this, AgilanbuGameOptionsActivity.class);
                startActivity(i);
            }
        }, 2000);
    }

1

您可以在onCreate方法中添加它

new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    // going to next activity
                    Intent i=new Intent(SplashScreenActivity.this,MainActivity.class);
                    startActivity(i);
                    finish();
                }
            },time);

并根据需要初始化以毫秒为单位的时间值...

private  static int time=5000;

有关更多详细信息,请从此链接下载完整代码...

https://github.com/Mr-Perfectt/Splash-Screen


1

在Kotlin中编写以下代码:-

 Handler().postDelayed({
            val mainIntent = Intent(this@SplashActivity, LoginActivity::class.java)
            startActivity(mainIntent)
            finish()
        }, 500)

希望这会对您有所帮助。谢谢........


0

简单的代码,它可以工作:) 简单的启动

int secondsDelayed = 1;
    new Handler().postDelayed(new Runnable() {
        public void run() {
            startActivity(new Intent(LoginSuccessFull.this, LoginActivity.class));
            finish();
        }
    }, secondsDelayed * 1500);

0
public class SplashActivity extends Activity {

  Context ctx;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      ctx = this;
      setContentView(R.layout.activity_splash);

      Thread thread = new Thread(){
          public void run(){
              try {
                  sleep(3000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }

              Intent in = new Intent(ctx,MainActivity.class);
              startActivity(in);
              finish();
          }
      };
      thread.start();
  }
}

这是一个不好的例子-如果您按下返回退出SplashActivity,会发生什么?该线程仍将执行。
Mark Keen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.