如何制作闪屏?

Eph*_*aim 509 android splash-screen

我想让我的应用看起来更专业,所以我决定要制作一个闪屏.

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

Abd*_*lah 544

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

当你打开任何Android应用程序时,你将默认获得一个黑色的屏幕,顶部有应用程序的标题和图标,你可以通过使用样式/主题来改变它.

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

<style name="splashScreenTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">
    <item name="android:windowBackground">@drawable/splash_screen</item>
</style>
Run Code Online (Sandbox Code Playgroud)

而不是使用@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" >
Run Code Online (Sandbox Code Playgroud)

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

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

更新 看看这篇文章https://plus.google.com/+AndroidDevelopers/posts/Z1Wwainpjhd 感谢@ mat1h和@adelriosantiago

  • 这是进行启动画面的正确方法.谢谢!有更多推迟投票的答案只是不好的做法.没有什么可以推迟用户看到第一个功能屏幕. (93认同)
  • 我遇到的一个问题是`<item name ="android:background">`会覆盖`windowBackground`.如果没有定义`android:background,我在任何片段中的背景将是透明的,揭示前景内容背后的活动. (7认同)
  • @Abdullah:我按照你说的方式跟着.它工作正常,但启动屏幕在活动转换时出现几毫秒. (4认同)
  • 在您的更新链接中,Google+ 已关闭,请与我们分享该损坏链接的内容 (3认同)
  • 是的,你需要,所以png的质量看起来很好 (2认同)
  • 似乎"父"仅在API 14及更高版本中受支持 (2认同)
  • @Abdullah谢谢!这将是一个可能的解决方案,但是我发现了这个:https://plus.google.com/+AndroidDevelopers/posts/Z1Wwainpjhd,为了避免为每个屏幕尺寸创建不同的图像,也可以创建包含图像的XML它在所有屏幕上看起来都很好. (2认同)
  • 我们如何将内容居中?对于具有内容大小等的不同设备呢? (2认同)
  • 有什么方法可以缩放吗? (2认同)

Upv*_*ote 481

进一步阅读:

老答案:

如何:简单的闪屏

此答案将向您展示如何在应用程序启动时显示启动屏幕一段时间,例如品牌推广.例如,您可以选择显示启动画面3秒钟.但是,如果您想要显示spash屏幕一段可变的时间(例如应用程序启动时间),您应该查看Abdullah的答案/sf/answers/1108242621/.但请注意,应用程序启动可能在新设备上非常快,因此用户只会看到一个不好的用户体验.

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

  <?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>
Run Code Online (Sandbox Code Playgroud)

而你的活动:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

就这样 ;)

  • 不要忘记在Manifest中添加splash (39认同)
  • 对于启动画面,这不是一个合适的解决方案,它会让用户等待显示启动画面,但启动画面的目的则相反.它应该在用户等待时显示闪屏.请参阅@ Abdullah的解决方案. (16认同)
  • @Peter问题不是如何在加载数据时显示启动画面. (8认同)
  • 而不是停止应用程序的'SPLASH_DISPLAY_LENGTH`时间.你应该这样做:https://www.bignerdranch.com/blog/splash-screens-the-right-way/ (4认同)
  • @ user2606414请在SO上创建一个问题,问题是粘贴整个错误日志. (3认同)
  • 许多评论,但没有人评论此解决方案中潜在的内存泄漏.我强烈推荐阅读这篇博文:http://www.codepond.org/2015/08/android-app-profiling-and-optimization.html (3认同)
  • 这段代码存在一个很大的问题,每次应用程序恢复时都会显示启动画面.怎么让它只在启动时出现?没有恢复. (2认同)

jam*_*mes 53

  • 创建一个活动:Splash
  • 创建布局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);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 更改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>
Run Code Online (Sandbox Code Playgroud)

  • 这不是启动画面的目的.这会造成额外的1秒延迟.在加载应用程序的第一个屏幕时,启动画面应该是图像.此链接可能有所帮助.http://stackoverflow.com/a/7057332/869451 (27认同)
  • 同意@ Suda.nese如果应用程序要求包括启动画面,那么它就是闪屏!当然,它可能不适合用户,但如果客户想要一个闪屏,那么通过gosh给他们 (5认同)
  • @efeyc:你100%正确..然而,当应用程序启动它看起来相当不错..你不觉得吗? (2认同)
  • @Suda.nese 绝对不是。用户不想看图片,用户想使用应用程序而不是有不必要的延迟 (2认同)

zdd*_*zdd 29

上面的答案非常好,但我想补充一些其他内容.我是Android的新手,我在开发过程中遇到了这些问题.希望这可以帮助像我这样的人.

  1. Splash屏幕是我的应用程序的入口点,因此在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>
    
    Run Code Online (Sandbox Code Playgroud)
  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();
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

快乐的编码!

  • 您可以在`AndroidManifest.xml`中添加`android:noHistory ="true"`以防止用户使用后退按钮返回启动画面. (10认同)

sab*_*aba 13

  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();
    }
     }
    
    Run Code Online (Sandbox Code Playgroud)
  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> 
    
    Run Code Online (Sandbox Code Playgroud)


小智 13

默认情况下,Splash Screnn不会自动使您的应用程序看起来更专业.专业设计的Splash Screen有可能使您的应用程序看起来更专业,但如果您不知道如何编写,那么您的应用程序的其余部分实际上将是多么专业.

关于拥有启动画面的唯一原因(借口)是因为您正在进行大量的计算或正在等待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 + sqplash+screen+source

所以有充分的理由不去做,但如果你确定你的情况不属于那些例子,那么上面给出了做到这一点的方法.确保它确实使您的应用程序看起来更专业,或者您已经击败了您为此做出的唯一理由.

它就像是一个YouTube频道,用一个冗长的图形介绍(和Outro)开始每个视频,或者感觉需要讲一个笑话或解释过去一周发生的事情(当它不是喜剧或LifeStyles频道时).只是展示节目!(只需运行程序).


Mah*_*ade 12

最重要的是答案非常好.但是存在内存泄漏问题.此问题在Android社区中通常称为"泄漏活动".那究竟是什么意思呢?

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

"泄漏活动"是指垃圾收集器无法清除旧活动实例的已分配内存的情况,因为它being (strong) referenced来自活动实例的对象.每个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Zee*_*bir 12

阿卜杜拉的回答很棒.但我想用我的答案添加更多细节.

实现启动画面

以正确的方式实现启动画面与您想象的有点不同.您看到的启动视图必须立即就绪,甚至在您可以在启动活动中为布局文件充气之前.

所以你不会使用布局文件.而是将启动画面的背景指定为活动的主题背景.为此,首先在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>
Run Code Online (Sandbox Code Playgroud)

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

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

<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/background_splash</item>
</style>
Run Code Online (Sandbox Code Playgroud)

这个主题必须有动作栏和我们刚才创建的背景.

在清单中,您需要将SplashTheme设置为要用作splash的活动.

<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>
Run Code Online (Sandbox Code Playgroud)

然后在您的活动代码中,在使用intent后使用者将用户导航到特定屏幕.

public class SplashActivity extends AppCompatActivity {

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

        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是正确的方法.我用这些参考文献来回答.

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

  • 我在 YouTube 上看到了一个关于这个的教程。但我认为位图大小将是问题,因为您无法使用 `layer-list` 调整它的大小。 (4认同)

小智 5

您不会使用布局文件。相反,将启动画面的背景指定为活动的主题背景。为此,首先在 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>
Run Code Online (Sandbox Code Playgroud)

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

接下来,您将在主题中将此设置为启动活动的背景。导航到您的 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>
Run Code Online (Sandbox Code Playgroud)

在新的 SplashTheme 中,将 window background 属性设置为 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>
Run Code Online (Sandbox Code Playgroud)

最后,您的 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

如果您确实有用于启动 Activity 的布局文件,则该布局文件只有在您的应用程序完全初始化后才会对用户可见,这为时已晚。您希望仅在应用程序初始化之前的那一小段时间内显示飞溅。


小智 5

不必要的在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>
Run Code Online (Sandbox Code Playgroud)

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

接下来,将其设置为主题中启动活动的背景。导航到您的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>
Run Code Online (Sandbox Code Playgroud)

在新的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>
Run Code Online (Sandbox Code Playgroud)

最后,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();
    }
}
Run Code Online (Sandbox Code Playgroud)

更多详细信息请阅读: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