在Android应用中实现启动画面的最佳方法是什么?

7

我需要为我的应用程序添加一个启动画面。 尝试创建一个包含启动画面图片的活动; 并尝试使用for循环和Timer类来引入时间延迟。但是这种方法行不通。 如果我错了,正确的方法是什么?


计时器方面具体有什么问题?那种方法应该是可行的。你能把你的代码粘贴过来吗? - Zach Rattner
可能重复的问题 https://dev59.com/lV7Va4cB1Zd3GeqPL6pM应用程序中的启动画面 - Sunny Kumar Aditya
如果你的答案与其他问题不同,应该发布你的答案,或者如果相同则删除帖子。 - Sababado
6个回答

16
上述解决方案不错,但如果用户在闪屏延迟结束之前按下返回键(并关闭应用程序),该怎么办?
应用程序可能仍会打开下一个 Activity,这并不是很友好的用户体验。
所以我使用自定义 Handler,在 onDestroy() 中删除所有未处理的消息。
public class SplashActivity extends Activity
{
    private final static int MSG_CONTINUE = 1234;
    private final static long DELAY = 2000;

    @Override
    protected void onCreate(Bundle args)
    {
        super.onCreate(args);
        setContentView(R.layout.activity_splash);

        mHandler.sendEmptyMessageDelayed(MSG_CONTINUE, DELAY);
    }

    @Override
    protected void onDestroy()
    {
        mHandler.removeMessages( MSG_CONTINUE );    
        super.onDestroy();
    }

    private void _continue()
    {
        startActivity(new Intent(this, SomeOtherActivity.class));
        finish();
    }

    private final Handler mHandler = new Handler()
    {
        public void handleMessage(android.os.Message msg)
        {
            switch(msg.what){
                case MSG_CONTINUE:
                    _continue();
                    break;
            }
        }
    };
}

我认为onPause是removeMessages()调用的更好选择。我发现onDestroy在生命周期中被调用太晚了,后续的Activity在点击返回后才出现。不过还是点个赞 :-) - barry

3

试试这个

public class SplashActivity extends Activity {
    Handler handler;
    private long timeDelay = 2000; //2 seconds
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.SplashLayout);
        final Intent i = new Intent(this, Landing.class);
        handler = new Handler(); 
        handler.postDelayed(new Runnable() { 
             public void run() { 
                 startActivity(i); 
                 finish();
             } 
        }, timeDelay); 
    }      
}

1

你可以只是延迟吗?

Thread delay = new Thread() {
    @Override
    public void run() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
        }

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                startNextActivity();
            }
        });
    }
};

1

试试这个,

protected int _splashTime = 15000; 

private Handler handler;
private Runnable runnable; 

private Context context;


@Override
public void onCreate(Bundle savedInstance)
{
    super.onCreate(savedInstance);
    setContentView(R.layout.splash);   

    final SplashScreen sPlashScreen = this; 

    handler = new Handler();

     runnable = new Runnable() {
         @Override
            public void run() { 
             try {
                handler.removeCallbacks(runnable);
                handler.postDelayed(runnable, _splashTime);
              }  
            finally {
                finish(); 
                //start a new activity

                //mtdCheckLicense();
                Intent main = new Intent();
                main.setClass(sPlashScreen, YourMainActivity.class);
                startActivity(main); 
                handler.removeCallbacks(runnable);

            }
        }
    }; 
    handler.postDelayed(runnable, 2000);
} 

应用程序会在启动时显示闪屏界面一段时间,然后进入主活动页面。在这段代码中,闪屏界面会等待2秒钟,然后启动主活动页面。


0
我在每个项目中最简单的做法如下所示:
public class SplashActivity extends Activity {
    protected boolean active = true;
    protected int splashTime = 1000;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash_screen);
        Thread splashTread = new Thread() {
            @Override
            public void run() {
                try {
                    int waited = 0;
                    while(active && (waited < splashTime)) {
                        sleep(100);
                        if(active) {
                            waited += 100;
                        }
                    }
                } catch(InterruptedException e) {
                    // do nothing
                } finally {
                    finish();
                    // Start your Activity here
               }
           }
       };
       splashTread.start();    
   }
 //...

0

使用这里描述的解决方案会浪费时间,因为它们在继续之前会暂停初始化2-3秒。

我更喜欢在main_activity.xml上面添加一个Splash Screen Layout。通过扩展Application来检测应用程序的第一次启动。如果是第一次启动,我会在后台构建UI时显示我的Splash-Screen...(如果进度条滞后,请使用后台线程!)

//Extend Application to save the value. You could also use getter/setter for this instead of Shared Preferences...
public class YourApplication extends Application {

    public static final String YOUR_APP_STARTUP = "APP_FIRST_START";

    @Override
    public void onCreate() {
        super.onCreate();

        //set SharedPreference value to true
        SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = mPreferences.edit();
        editor.putBoolean(YOUR_APP_STARTUP, true);
        editor.apply();     
        ...    
     }

在你的MainActivity中检查你的第一次启动

public class YourMainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //hide actionbar and other menu which could overlay the splash screen
    getActionBar().hide();

    setContentView(R.layout.activity_main);

    Boolean firstStart = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(TVApplication.YOUR_APP_STARTUP, true);

    if (firstStart) {
        //First app start, show splash screen an hide it after 5000ms
        final RelativeLayout mSplashScreen = (RelativeLayout) findViewById(R.id.splash_screen);
        mSplashScreen.setVisibility(View.VISIBLE);
        mSplashScreen.setAlpha(1.0f);
        final FrameLayout mFrame = (FrameLayout) findViewById(R.id.frame_container);
        mFrame.setAlpha(0.0f);

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Animation fadeOutAnimation = AnimationUtils.loadAnimation(getApplicationContext(),
                        R.anim.fade_out_animation);
                fadeOutAnimation.setDuration(500);
                fadeOutAnimation.setAnimationListener(new Animation.AnimationListener() {

                    @Override
                    public void onAnimationStart(Animation animation) {
                        mFrame.setAlpha(1.0f);
                        getActionBar().show();
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        mSplashScreen.setVisibility(View.GONE);
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {

                    }
                });
                mSplashScreen.startAnimation(fadeOutAnimation);
            }
        }, 5000); //<-- time of Splash Screen shown

    } else {
        ((RelativeLayout) findViewById(R.id.splash_screen)).setVisibility(View.GONE);
        getActionBar().show();
    }

在你的main.xml文件中,在顶部插入SplashScreen。我更喜欢使用RelativeLayout。在这个例子中,SplashScreen被放置在一个带有导航抽屉的布局上方,我们真的很喜欢它,不是吗?

//main_activity.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.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <!-- The main content view -->

        <FrameLayout
            android:id="@+id/frame_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <!-- The navigation drawer list -->

        <ListView
            android:id="@+id/slider_list"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_alignParentTop="true"
            android:layout_gravity="start"
            android:background="@color/tvtv_background"
            android:choiceMode="singleChoice"
            android:divider="@drawable/nav_bar_divider"
            android:dividerHeight="1dp"
            android:listSelector="@android:color/transparent" />
    </android.support.v4.widget.DrawerLayout>

    <RelativeLayout
        android:id="@+id/splash_screen"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:background="@color/tvtv_white"
        android:visibility="visible" >

        <ImageView
            android:id="@+id/splash_screen_logo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:paddingLeft="50dp"
            android:paddingRight="50dp"
            android:scaleType="fitCenter"
            android:src="@drawable/ic_launcher" />

        <TextView
            android:id="@+id/splash_screen_text"
            style="@style/TVTextBlueContent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/splash_screen_logo"
            android:layout_centerHorizontal="true"
            android:padding="10dp"
            android:text="Awesome splash shiat" />

        <ProgressBar
            android:id="@+id/splash_screen_loader"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/splash_screen_text"
            android:layout_centerHorizontal="true"
            android:clickable="false"
            android:indeterminate="true" />
    </RelativeLayout>

</RelativeLayout>   

1
这意味着你的启动屏将始终在你的视图层次结构中,即使你没有使用它。如果你想使用这种方法,最好使用ViewStub。http://developer.android.com/reference/android/view/ViewStub.html - Jelle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接