【问题标题】:Android SplashScreen安卓闪屏
【发布时间】:2010-12-31 01:46:20
【问题描述】:

我正在开发一个应用程序,它基本上在应用程序本身开始时下载大量数据并将其显示在 ListActivity 中。我打算做的是在加载数据之前显示一个启动画面。

到目前为止,我所有的尝试都是徒劳的。我尝试了 anddev.org 提到的方法,但我的问题是主 Activity 应该启动但在我填充我的 ListActivity 之前启动画面应该是可见的。所以简而言之我必须经过以下步骤:

  1. 开始我的主要活动。
  2. 显示启动画面。
  3. 继续在后台运行进程。
  4. 处理完成后退出启动画面并显示主列表。

希望你明白它是什么样的......

【问题讨论】:

  • 任何人都可以解释一下,即使我尝试在主列表的 OnCreate 函数中创建并启动它,即使进度条也没有加载...并在我的过程完成后将其关闭...甚至这不起作用...我的意思是我需要遵循任何默认方法...例如在 OnStart() 中启动进度条之类的??
  • 您是否尝试过stackoverflow.com/questions/2222890/… 中接受的答案所说的内容?编辑:好的,接受的答案有点相同..

标签: android splash-screen


【解决方案1】:

问题很可能是您在与所有正在完成的工作相同的线程中运行启动屏幕(某种Dialog,例如ProgressDialog)。这将防止启动屏幕的视图被更新,这甚至可以防止它显示到屏幕上。您需要显示启动画面,启动AsyncTask 的实例以下载所有数据,然后在任务完成后隐藏启动画面。

因此,您的 Activity 的 onCreate() 方法将简单地创建一个 ProgressDialog 并显示它。然后创建 AsyncTask 并启动它。我会将 AsyncTask 设为主 Activity 的内部类,这样它就可以将下载的数据存储到 Activity 中的某个变量中,并在其 onPostExecute() 方法中关闭 ProgressDialog。

不知道如何在不显示代码的情况下再详细说明,所以这里是:

public class MyActivity extends Activity {
    private ProgressDialog pd = null;
    private Object data = null;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Show the ProgressDialog on this thread
        this.pd = ProgressDialog.show(this, "Working..", "Downloading Data...", true, false);

        // Start a new thread that will download all the data
        new DownloadTask().execute("Any parameters my download task needs here");
    }

    private class DownloadTask extends AsyncTask<String, Void, Object> {
         protected Object doInBackground(String... args) {
             Log.i("MyApp", "Background thread starting");

             // This is where you would do all the work of downloading your data

             return "replace this with your data object";
         }

         protected void onPostExecute(Object result) {
             // Pass the result data back to the main activity
             MyActivity.this.data = result;

             if (MyActivity.this.pd != null) {
                 MyActivity.this.pd.dismiss();
             }
         }
    }    
}

显然你需要在那里填写一些内容,但是这段代码应该可以运行并为你提供一个很好的起点(如果有代码错误,请原谅我,我无法访问 Android SDK,因为我'我正在输入这个)。

可以在herehere 找到更多关于Android AsyncTasks 主题的好读物。

【讨论】:

  • 返回“替换为数据对象”是什么意思?我有两个函数,我想像你说的那样在 asynctask 中加载,但我不知道我应该返回什么。我试图返回 null 但应用程序崩溃了。
  • AsyncTask 其中 Object 表示您要返回的数据类型。请参阅此处的“AsyncTask 的泛型类型”部分:developer.android.com/reference/android/os/AsyncTask.html
  • 这很旧,我知道,但我已经尝试过实现它并且ProgressDialog(在我的情况下是加载布局的常规对话框)从未显示。如果我在onPostExecute 中注释掉.dismiss(),我只会看到它。我看到的第一个屏幕仍然是MyActivity 主题。之后直接转到R.layout.main
  • @Kevin_TA 如果 .dismiss() 导致它不显示,那么您的 AsyncTask 将立即结束。我概述的方法是在一些长时间运行的启动任务运行时显示一个启动屏幕。
  • @mbaird 它不会立即结束。我确实有一个需要 2-3 秒才能完成的后台进程。但由于某种原因,在异步完成之前,UI 上的任何内容都不会更新,从而违背了目的。
【解决方案2】:

仅供参考,这是我发现制作启动画面的最佳方式: http://android-developers.blogspot.de/2009/03/window-backgrounds-ui-speed.html

我在 androids 文档中搜索了很长时间。如果你想避免那些黑屏,你需要创建一个带有 windowBackground 的主题,所以:

<resources>
    <style name="Theme.Shelves" parent="android:Theme">
        <item name="android:windowBackground">@drawable/background_shelf</item>
        <item name="android:windowNoTitle">true</item>
    </style>
</resources>

并将此主题设置为您的主要活动的主题... TADA,从第一秒开始的闪屏。

如果您想要一个复杂的背景,而不仅仅是一个将被拉伸以填充的图像,您可以使用 Drawables,这里是一个图层列表的示例,它将使徽标以黑色背景居中:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:drawable="@color/black">
    </item>
    <item>
        <bitmap
            android:gravity="center"
            android:src="@drawable/logo"
            android:tileMode="disabled" >
        </bitmap>
    </item>
</layer-list>

【讨论】:

  • 此链接已失效,但页面内容和源代码可在archive.org 上找到:web.archive.org/web/20101113015720/http://developer.android.com/…
  • 有没有办法使用 layout.xml 而不是 android:windowBackground 的可绘制对象?尝试这样做时发生崩溃,但我想知道是否有解决方法。
  • @Kevin_TA 不,没有。但是你可以使用 Drawables,所以如果你想在屏幕中间有一个 Logo,那么你应该使用 layer-list drawable 并使用重力来定位你的图像。我会用一个例子来更新答案。
  • @Ranaan Theme 解决方案对我有用,但我应该如何将 layer-list 连接到主题?
  • @deko item name="android:windowBackground" 可以是固定颜色或图像,也可以是放置在 res/drawable 文件夹中的 xml 可绘制图层列表。您可以在此处阅读有关 Drawables 的信息:developer.android.com/guide/topics/resources/…
【解决方案3】:

启动画面示例:

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

    }

}

【讨论】:

    【解决方案4】:
    1. 开始我的主要活动。
    2. 显示启动画面。
    3. 继续在后台运行进程。
    4. 处理完成后退出启动画面并显示主列表。

    我试过这种方式,但问题是;它会在启动闪屏活动之前显示主要活动。

    我是这样弄的:

    1. 启动启动画面
    2. 流程完成后,启动“主要活动”
    3. 不要忘记处理后退按钮,所以它应该关闭应用程序 isist 将在主活动中按下。否则会回到启动画面(循环)

    我的问题是如何通过按菜单按钮来禁用“显示启动屏幕活动的菜单”。

    编辑:

    禁用显示菜单:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // getMenuInflater().inflate(R.menu.activity_main, menu);
        return false;
    }
    
    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {       
        // return super.onMenuItemSelected(featureId, item);
        return false;
    }
    

    【讨论】:

      【解决方案5】:

      我知道这个问题已经很老了,OP 可能不再需要它了。但我只是想添加这个答案来帮助可能需要它的人存档启动画面。

      回答 (仅适用于 Android Oreo 或更高版本)


      实际上,在较新版本的 Android 中(Android Oreo 之后),它已经支持内置闪屏工具。这意味着您不需要创建额外的活动来执行此操作。您只需要一个可绘制的资源文件即可显示。

      使用这种方式可以更快地显示初始屏幕,并在初始化后很快显示您的内容。但请注意,这只适用于 Android Oreo 或更高版本。在以前的版本中,它会显示白色而不是启动画面(至少我是这么认为的)。

      您的 AppTheme 样式中需要此行:

      <item name="android:windowSplashscreenContent">@drawable/YOUR_SPLASH_SCREEN_DRAWABLE</item>
      

      这是一个完整的例子:

      <!-- Base application theme. -->
      <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
          <!-- Customize your theme here. -->
      
          <!-- Set your splash screen here, it accept a resource from drawable directory-->
          <item name="android:windowSplashscreenContent" tools:targetApi="o">@drawable/splash_screen</item>
      </style>
      

      参考


      关于此属性的更多信息,请参阅此处的官方参考:https://developer.android.com/reference/android/R.attr#windowSplashscreenContent

      正如它所说,它是在 API 级别 26 中添加的。

      以及它所说的简短摘录:

      对可用作窗口启动画面内容的可绘制对象的引用。此可绘制对象将放置在windowBackground 的顶部,其边界由系统栏插入。如果系统栏不应插入可绘制对象,请使用全屏主题。

      请注意,即使主题上没有设置闪屏内容,系统仍可能使用主题上的其他属性显示闪屏,例如windowBackground

      【讨论】:

      • 这与您在此处发布的内容相同:stackoverflow.com/a/65783070/549372
      • @Martin Zeitler 我已经删除了该答案,因为它与该问题无关。我把它移到了这里,所以它更相关。
      猜你喜欢
      • 2021-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      • 1970-01-01
      • 1970-01-01
      • 2011-06-25
      相关资源
      最近更新 更多