我如何制作启animation面?

我想让我的应用程序看起来更专业,所以我决定要做一个启animation面。

我将如何创build它,然后执行它?

进一步阅读:

  • 应用程序启动时间和主题启动屏幕(Android性能模式季节6第4集)
  • Android中的初始屏幕:正确的方法

老答案:

如何 : 简单的启animation面

这个答案显示了当你的应用程序启动时如何显示一个固定时间的启animation面,例如品牌的原因。 例如,您可能select显示启animation面3秒钟。 但是,如果你想显示spash屏幕的时间可变(例如应用程序启动时间),你应该检查出阿卜杜拉的答案https://stackoverflow.com/a/15832037/401025 。 不过请注意,在新设备上应用启动速度可能会非常快,所以用户只会看到一个坏的用户体验。

首先,您需要在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> 

而你的活动:

 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); } } 

就这样 ;)

请注意,此解决scheme不会让用户多等待:启animation面的延迟取决于应用程序的启动时间。

当你打开任何Android应用程序,你会得到一个什么样的黑色屏幕上的应用程序的标题和图标,你可以通过使用风格/主题来改变。

首先,在values文件夹中创build一个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); } 

更新看看这个posthttps://plus.google.com/+AndroidDevelopers/posts/Z1Wwainpjhd感谢@ mat1h和@adelriosantiago

  • 创build一个活动:飞溅
  • 创build一个布局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> 

@阿卜杜拉的答案是正确的,但是Google已经发布了一个关于如何在不改变你的活动主题的情况下正确实现这个function的扩展解释:

https://plus.google.com/+AndroidDevelopers/posts/Z1Wwainpjhd

Google地图和YouTube等应用已经开始使用相同的方法。

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

  1. 启animation面是我的应用程序的入口点,所以在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. 启animation面应该只在应用程序生命周期中显示一次,我使用布尔variables来logging启animation面的状态,并且只在第一次显示。

     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(); } } } 

快乐的编码!

  1. 创build一个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> 

Splash Screnn默认情况下不会自动使您的应用程序看起来更专业。 一个专业devise的闪屏有可能使你的应用程序看起来更专业,但如果你不知道如何写一个,那么你的应用程序的其余部分实际上会有多专业。

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

这样的屏幕应该看起来像你的全屏应用程序给人的印象,它已经初始化,然后长时间的计算完成后,最后的细节可以填写(图像调整)。 这样做的可能性 ,或者这是计划devise的唯一方式, 是非常小的

允许用户(和其他操作系统)在等待的时候做一些其他的事情,而不是devise你的程序依赖于需要一段时间(等待时间不确定)的东西。

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

如果你绝对必须等待这些计算或GPS / WiFi,最好只是让应用程序启动,并popup说,有必要等待计算(一个TEXTUAL“初始化”消息是好的)。 预计等待GPS / WiFi(如果它们还没有在另一个程序中启用),所以宣布等待时间是不必要的。

请记住,当启animation面启动时,程序实际上已经在运行了,你所做的只是延迟程序的使用,让CPU / GPU去做一些大多数人觉得没有必要的事情。

每当我们开始你的程序,我们最好真的想等待,看看你的启animation面,否则我们不会觉得它是非常专业的写作。 使飞溅屏幕全屏幕和实际程序的屏幕(所以我们认为它已经初始化,但事实上它没有)可能实现您的目标(使您的程序看起来更专业)的副本,但我不会在这方面下很多。

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

如何执行此操作: https : //encrypted.google.com/search?q = Android + splash + screen + source

所以有一个很好的理由不这样做,但如果你确定你的情况不在这些范例之内,那么上面给出了做这件事的方法。 确定它确实确实使你的应用程序看起来更专业,或者你已经击败了你为此所做的唯一理由。

这就像一个YouTube频道,每个video都有一个漫长的Graphic Intro(和Outro),或者觉得有必要告诉一个笑话或者解释过去一周发生了什么(当它不是一个喜剧或LifeStyles频道时)。 只显示节目! (只需运行该程序)。

以上所有答案都非常好。 但是也有遇到内存泄漏的问题。 这个问题在Android社区中常常被称为“泄漏活动” 。 那到底是什么意思?

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

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

如何确定应用程序是否泄漏内存? 最快的方法是在Android Studio中打开“内存”选项卡,并在更改方向时注意分配的内存。 如果分配的内存不断增加,永远不会减less,那么你有内存泄漏。

1.用户改变方向时存储器泄漏。 在这里输入图像描述

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

启animation面活动的示例代码。

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

欲了解更多信息,请通过此链接

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

实现一个初始屏幕

以正确的方式实现启animation面与您想象的有一点不同。 您看到的飞溅视图必须立即准备好,甚至在可以在飞溅活动中膨胀布局文件之前。

所以你不会使用布局文件。 相反,请将启animation面的背景指定为活动的主题背景。 为此,首先在res / drawable中创build一个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> 

这个主题将不得不动作栏和我们刚刚创build的背景。

在清单中,您需要将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/感谢这些家伙把我推向正确的方向。; 我想帮助别人,因为接受的答案不是build议做闪屏。

这里是完整的代码

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); }} 

在drawables中创build这个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中创build一个自定义主题

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

干杯。

启动屏幕不应该从布局文件加载,加载时可能仍然有一些滞后。

最好的方法是为你的SplashScreenActivity创build一个主题,并将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(); } 

接下来创build你的主题的背景窗口的资源:

 <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> 
 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(); } 

闪屏示例:

 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); } } 

启animation面在Android中是一个不太可用的对象:它不能尽快加载,以隐藏主要活动启动的延迟。 使用它有两个原因:广告和networking运营。

作为对话的实施使得从闪屏到活动的主UI的跳跃没有延迟。

 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(); } ... } 

在Android Marshmallow之后 ,其他的Splash屏幕的生产使用我想到的是在你的应用程序的启animation面中请求必要的Android Permissions

它似乎像大多数应用程序处理权限请求这种方式。

  • 对话使得糟糕的UIX,他们打破了主stream,让你决定在运行时,真相是大多数用户可能不关心,如果你的应用程序要写在SD卡上的东西。 他们中的一些可能甚至不明白我们要传达的东西,直到我们用纯英文翻译它。

  • 在每次操作之前,一次请求权限会使“if else”的数量减less,并使您的代码看起来没有任何问题。

这是一个如何在运行Android OS 23+的设备上针对您的初始活动请求权限的示例。

如果所有的权限被授予或已经授予,或者应用程序在Pre棉花糖上运行,那么只需稍稍延迟一秒钟就可以显示主要内容,以便用户可以欣赏我们在阅读这个问题时所付出的努力,并尽力给予我们最大的努力。

 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); } } 

创build一个活动,让我们活动名为“A”,然后创build一个名为myscreen.xml的xml文件,在那里设置一个闪屏图像作为背景,然后使用倒数计时器从一个活动导航到另一个。 要知道如何使用倒数计时器看到我的答案在这个问题在Android的TimerTask?

如何使用相同的代码并在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(); } } } 

你将不会使用布局文件。 相反,请将启animation面的背景指定为活动的主题背景。 为此,首先在res / drawable中创build一个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文件并为您的splash活动添加一个新的主题:

 <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中,将窗口背景属性设置为您的XML可绘制。 在你的AndroidManifest.xml中将它configuration为你的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> </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时,它立即可用。

如果您的飞溅活动确实有布局文件,那么仅当您的应用完全初始化后,该布局文件才会对用户可见,这太晚了。 你只想在应用程序初始化之前的短时间内显示飞溅。

另一种方法是通过使用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(); } 

有时用户打开SplashActivity并立即退出,但应用程序仍然在SPLASH_SCREEN_DISPLAY_LENGTH之后进入MainActivity

为了防止它:在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); } } } 

希望这个帮助

虽然有很好的答案,但我会展示google推荐的方式:

1)首先创build一个闪屏的主题:你有一个主题叫splashscreenTheme ,你的发射主题是:

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

注意:

android:windowBackground已经设置你的splashscreen图像号
需要再次在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文件夹中。

这将导致更快的启动屏幕启动,并将您从黑屏保存

它也避免了额外的透支

这是我见过的最好的post: http : //saulmm.github.io/avoding-android-cold-starts

SaúlMolinero进入了两个不同的启animation面选项:利用窗口背景在最初的屏幕上进行animation制作,并显示占位符UI(这是目前Google大多数应用程序的stream行select)。

每次我需要考虑冷启动时间,并避免由于启动时间过长造成的用户丢失,我都会参考这篇文章。

希望这可以帮助!

简单的代码,它的作品:) 简单的飞溅

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

不必要的停留在4秒5的Splash屏幕没有多大意义。 如果你在后台加载某些东西,那么就可以了,否则按照这个方法实现启animation面: –以正确的方式实现启animation面与你想象的有一点不同。 您看到的飞溅视图必须立即准备好,甚至在可以在飞溅活动中膨胀布局文件之前。

所以你不会使用布局文件。 相反,请将启animation面的背景指定为活动的主题背景。 为此,首先在res / drawable中创build一个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文件并为您的splash活动添加一个新的主题:

 <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中,将窗口背景属性设置为您的XML可绘制。 在你的AndroidManifest.xml中将它configuration为你的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> </activity> 

Finally, SplashActivity class should just forward you along to your main activity:

  public class SplashActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = new Intent(this, MainActivity.class); startActivity(intent); finish(); } } 

More Details read this: 1. https://www.bignerdranch.com/blog/splash-screens-the-right-way/ 2. http://blog.goodbarber.com/3-tips-to-create-a-great-splash-screen-for-your-mobile-app_a287.html

activity_splash.xml

 <?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" android:background="@drawable/gradient_background" > <ImageView android:id="@+id/imgLogo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@drawable/wwe_logo" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:textSize="12dp" android:textColor="#454545" android:gravity="center_horizontal" android:layout_alignParentBottom="true" android:text="www.androidhive.info" /> </RelativeLayout> 

SplashScreen.java

 import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; public class SplashScreen extends Activity { // Splash screen timer private static int SPLASH_TIME_OUT = 3000; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); 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() { // This method will be executed once the timer is over // Start your app main activity Intent i = new Intent(SplashScreen.this, MainActivity.class); startActivity(i); // close this activity finish(); } }, SPLASH_TIME_OUT); } } 

输出:

在这里输入图像描述

 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(); } }