Android SplashScreen


80

我正在开发一个应用程序,它基本上会在应用程序本身的开始处下载大量数据,并将其显示在ListActivity中。我打算做的是显示一个启动屏幕,直到加载数据。

到现在为止,我所有的尝试都是徒劳的。我尝试了anddev.org提到的方法,但是我的问题是主要的Activity应该启动,但在我填充ListActivity之前,初始屏幕应该可见。简而言之,我必须执行以下步骤:

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

希望你了解它的样子。


即使我尝试在主列表的OnCreate函数中创建并启动它,也无法加载进度条,甚至在我的程序完成后将其关闭...意思是我需要遵循任何默认方法吗……比如在OnStart()中启动进度栏之类的?
2009年

您是否尝试了stackoverflow.com/questions/2222890/…中可接受的答案说了什么?编辑:好的,公认的答案是有点相同..
noloman

Answers:


89

问题很可能是您在完成所有工作的同时在同一线程中运行启动屏幕(某种对话框,例如我假设的ProgressDialog)。这将使初始屏幕的视图不会被更新,甚至可以使其不显示在屏幕上。您需要显示初始屏幕,启动AsyncTask的实例以下载所有数据,然后在任务完成后隐藏初始屏幕。

因此,您Activity的onCreate()方法将只创建一个ProgressDialog并显示它。然后创建AsyncTask并启动它。我将AsyncTask设置为主活动的内部类,以便它可以将已下载的数据存储到活动中的某个变量中,并在其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)目前)。

这里这里都可以找到关于Android中AsyncTasks主题的更多不错的阅读。


返回“用数据对象替换”是什么意思?我有两个函数要像您所说的那样加载到asynctask中,但是我不知道该返回什么。我试图返回null,但应用程序崩溃。
尼克

AsyncTask <String,Void,Object>其中,Object表示要返回的数据类型。请参阅此处的“ AsyncTask的通用类型”部分:developer.android.com/reference/android/os/AsyncTask.html
Mark B

我知道这很旧,但是我已经尝试实现了这一点,并且ProgressDialog(在我的情况下,是一个常规的Dialog加载布局)从未显示。只有在.dismiss()中删除时,我才能看到它onPostExecute。我看到的第一个屏幕仍然是MyActivity主题。之后,它直接进入R.layout.main
Kevin_TA 2014年

@Kevin_TA如果.dismiss()使其不显示,则您的AsyncTask立即结束。我概述的方法用于显示启动屏幕,该启动屏幕在某些长时间运行的启动任务运行时显示。
马克B

@mbaird它不会立即结束。我确实有一个后台过程,需要2-3秒才能完成。但是由于某种原因,直到完成异步之后,UI上的任何内容都不会更新,因此无法达到目的。
Kevin_TA 2014年

61

仅供参考,这是我发现制作初始屏幕的最佳方法:http : //android-developers.blogspot.de/2009/03/window-backgrounds-ui-speed.html

我在Android文档中搜索了很长时间。如果您想避免黑屏,则需要使用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>

1
该链接已失效,但是页面内容和源代码可在archive.org上找到:web.archive.org/web/20101113015720/http
//developer.android.com/…– Spoonface 2012年

有没有办法为Android:windowBackground使用layout.xml而不是drawable?尝试这样做时发生崩溃,但我想知道是否有解决方法。
Kevin_TA 2014年

@Kevin_TA不,没有。但是您可以使用Drawables,因此,如果要在屏幕中间显示徽标,则应该使用图层列表可绘制对象,并使用重力放置图像。我将用示例更新答案。
拉南2014年

1
@Ranaan主题解决方案适用于我,但如何将图层列表连接到主题?
deko 2014年

2
@deko item name =“ android:windowBackground”可以是固定颜色或图像,也可以是xml可绘制对象,例如放置在res / drawable文件夹中的layer-list。:你可以在这里读到绘项目developer.android.com/guide/topics/resources/...
Raanan

1

启动画面示例:

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

    }

}

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

我尝试过这种方式,但是问题是;在启动初始屏幕活动之前,它将显示主要活动。

我是这样写的:

  1. 启动启动画面
  2. 流程完成后,开始“主要活动”
  3. 不要忘记处理后退按钮,因此应将其关闭,在主活动中将按下该按钮。否则将返回初始屏幕(循环)

我的问题是如何通过按菜单按钮禁用“显示启动画面的菜单”。

编辑:

禁用显示菜单:

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