我希望我的应用程序看起来更加专业,因此我决定添加一个启动画面。
我该如何实现它?
我希望我的应用程序看起来更加专业,因此我决定添加一个启动画面。
我该如何实现它?
请注意,此解决方案不会让用户等待更长时间:启动画面的延迟取决于应用程序的启动时间。
当您打开任何Android应用程序时,默认情况下会出现一个略带黑色背景的屏幕,顶部显示应用程序的标题和图标,您可以通过使用样式/主题来更改它。
首先,在值文件夹中创建一个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
<item name="android:background">
会覆盖windowBackground
。如果没有定义android:background
,在任何片段中我的背景都将透明,显示前景内容后面的活动背景。 - William Grand进一步阅读:
旧答案:
如何实现: 简单闪屏页
此答案向您展示了如何在应用程序启动时显示一个固定时间的闪屏页,例如出于品牌推广的原因。例如,您可以选择展示3秒钟的闪屏页。但是如果您想要展示一个变量时间长度的闪屏页(例如应用程序启动时间),则应查看阿卜杜拉的答案https://dev59.com/3W035IYBdhLWcg3wVebn#15832037。然而请注意,新设备的应用程序启动可能非常快,因此用户只会看到闪烁的屏幕,这是不好的用户体验。
首先,您需要在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);
}
}
就是这样了;)
SPLASH_DISPLAY_LENGTH
时间来阻塞应用程序,相反你应该采用以下方法:https://www.bignerdranch.com/blog/splash-screens-the-right-way/ - miguel.martin你的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>
以上回答非常好,但我想再补充一些内容。我是Android新手,在开发过程中遇到了这些问题。希望这可以帮助像我一样的人。
启动画面是我的应用程序的入口点,因此请在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>
启动画面应该只在应用程序生命周期中显示一次,我使用一个布尔变量来记录启动画面的状态,并仅在第一次显示它。
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();
}
}
}
愉快编码!
AndroidManifest.xml
中添加android:noHistory="true"
来防止用户使用返回按钮回到闪屏界面。 - RachelAbdullah的回答很好,但我想在我的回答中添加更多细节。
实现闪屏界面
正确实现闪屏界面与你想象中有些不同。你看到的闪屏界面必须立即准备好,即使在你的闪屏活动中填充布局文件之前也是如此。
因此,你将不会使用布局文件。相反,将闪屏界面的背景指定为活动的主题背景。为此,请先在res/drawable中创建一个XML可绘制对象。
background_splash.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Background Color -->
<item
android:drawable="@color/gray"/>
<!-- Logo -->
<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();
}
}
这就是正确的做法。我使用了这些参考资料来回答问题:
YouTube
上看到了相关的教程。但我认为位图大小会是个问题,因为你不能使用 layer-list
来调整它的大小。 - RoCkDevstack<bitmap>
标签,这可能会引发ResourceNotFound异常;而是直接在<item>
中使用android:drawable
代替android:src
。 - ZainwindowBackground
中吗?或者在相关的layer-list中呢? - C.F.G创建一个名为SplashScreen.java
的Activity
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();
}
}
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>
默认情况下,闪屏并不能使您的应用程序看起来更加专业。如果您不知道如何编写一个专业设计的闪屏,则其实际上如何专业化的程序是很值得考虑的。
唯一需要有闪屏的原因(借口)就是因为您正在进行大量计算或者正在等待GPS / WiFi启动,因为您的应用程序在启动之前依赖于它们。如果没有这些计算结果或对GPS / WiFi等的访问权限,您的应用程序就无法使用,因此您认为需要一个闪屏,并且必须阻止其他正在运行的程序(包括后台)的视图。
这样的闪屏应该看起来像您的全屏应用程序,以给人初始化的印象,然后在完成漫长的计算后,可以填写最后的细节(调整图像)。这种情况发生的可能性非常小,或者说这是程序设计的唯一方式是极其罕见的。
最好的方法是允许用户(和其他操作系统)在等待期间做其他事情,而不是将您的程序设计成依赖于需要一段时间的工作(等待的持续时间不确定)。
您的手机上已经有显示GPS / WiFi正在启动的图标了。闪屏占用的时间或空间可以用来加载预先计算或实际进行计算。有关您所造成的问题以及必须考虑的问题,请参见下面的第一个链接。
如果您绝对必须等待这些计算或GPS / WiFi,最好只需让应用程序启动,并弹出一条消息,说明需要等待计算(文字上的“初始化”消息就可以)。 GPS / WiFi的等待是可以预料到的(如果它们没有在另一个程序中启用),因此宣布它们的等待时间是不必要的。
请记住,当闪屏启动时,您的程序已经在运行,您所做的只是延迟使用您的程序并占用CPU / GPU来执行大多数人认为不必要的操作。
我们最好每次启动程序时都想要看到你的启动画面,否则我们就感觉它写得不太专业。将启动画面设置为全屏,并复制实际程序屏幕的内容(这样我们认为程序已经初始化了,实际上并没有),可能能实现你的目标(使你的程序看起来更专业),但我不会把赌注压在这个上面。以上所有答案都非常好。但是存在内存泄漏的问题。
在Android社区中,这个问题通常被称为"Leaking an Activity"。那么这到底是什么意思呢?
当发生配置更改时(如方向更改),Android会销毁Activity并重新创建它。通常,垃圾回收器只会清除旧Activity实例的分配内存,然后我们就可以了。
"Leaking an Activity"是指垃圾回收器无法清除旧Activity实例的分配内存,因为它被一个超出Activity实例寿命的对象引用(strong reference)着。每个Android应用程序都有一定数量的内存分配给它。当垃圾回收器无法释放未使用的内存时,应用程序的性能将逐渐降低,并最终崩溃并显示OutOfMemory
错误信息。
如何确定应用程序是否存在内存泄漏?最快的方法是在Android Studio中打开内存选项卡,并在更改方向时注意分配的内存量。如果分配的内存保持增加而不减少,则表示存在内存泄漏。
首先,您需要在布局资源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;
}
}
更多信息请查阅此链接
以下是完整的代码
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);
}}
<?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>
<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>
干杯。
drawable
? - viper闪屏界面不应该从布局文件中加载,否则在加载时可能会有一些延迟。
最好的方法是为您的SplashScreenActivity创建一个Theme,并将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>