2014/12/06

[Android] 利用AsyncTask和Progressbar來做APP起始畫面(SplashScreen)

許多的程式都會擺上自家的品牌Logo,做成所謂的起始畫面(Splash Screen),除了可以邊讀取資料之外,也算是幫自家廣告。那麼起始畫面要怎麼來實作呢?

分成幾個部分,負責起始畫面的SplashScreenActivity,用AsyncTask產生ProgressBar效果的SplashScreenAsyncTask,完成之後切換到主要畫面的MainActivity。




一、建立Splash Screen畫面的SplashScreenActivity
Androrid的畫面都會伴隨著ActionBar,為了要做起始畫面,就不能夠讓ActionBar顯示出來,所以在Activity的onCreate之中要把ActionBar的title隱藏。
requestWindowFeature(Window.FEATURE_NO_TITLE);

除了這樣還不夠,還要讓一開始把程式載入時的起始畫面隱藏,不然開啟程式一開始看到的就不會是起始畫面,而還是會看到預設的畫面。這個部分要在AndroidManifest.xml做設定。
android:theme="@android:style/Theme.Black.NoTitleBar"

最後建立好SplashScreenActivity之後,要把一開始載入的activity更換
<activity
    android:name="com.example.splashscreen.SplashScreenActivity"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Black.NoTitleBar" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

二、ProgressBar效果
配合AsyncTask來使用,AsyncTask的使用可以參考這篇。這部分主要要注意ProgressBar的設定。設定為setVisibility(View.GONE)可以讓ProgressBar隱藏且不占資源;如果是setVisibility(View.INVISIBLE)也會隱藏,但是會佔資源;而setVisibility(View.VISIBLE)則是讓ProgressBar顯示出來。
spinbar.setVisibility(View.GONE);
spinbar.setVisibility(View.VISIBLE);
spinbar.setVisibility(View.INVISIBLE);

三、程式碼
MainActivity.java
package com.example.splashscreen;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

 // String for LogCat documentation
 private final static String TAG = "SplashScreen-MainActivity";
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  Log.i(TAG, "onCreate().");
 }
}

activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

SplashScreenActivity.java
package com.example.splashscreen;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.ProgressBar;

public class SplashScreenActivity extends Activity {
 
 // String for LogCat documentation
 private final static String TAG = "SplashScreen-SplashScreenActivity";
 private ProgressBar spinbar;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  requestWindowFeature(Window.FEATURE_NO_TITLE);
  super.onCreate(savedInstanceState);
  setContentView(R.layout.splashscreen);
  Log.i(TAG, "onCreate().");
  
  spinbar = (ProgressBar) findViewById(R.id.progressBar1);
  spinbar.setVisibility(View.GONE);
  new SplashScreenAsyncTask(this, spinbar).execute();
  
 }
}

splashscreen.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/splash_screen"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:orientation="vertical" >
        
  <Space
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2" />
  
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:text="Welcome!"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <Space
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical" >

        <ProgressBar
            android:id="@+id/progressBar1"
            style="?android:attr/progressBarStyleLarge"
            android:layout_gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>

</LinearLayout>

SplashScreenAsyncTask.java
package com.example.splashscreen;

import java.net.URL;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;

public class SplashScreenAsyncTask extends AsyncTask<URL, Integer, String> {
 
 // String for LogCat documentation
 private final static String TAG = "SplashScreen-AsyncTask";
 private Activity mParentActivity;
 
 private int waitnumber = 10;
 private String doInReturn = "ok";
 private ProgressBar spinTask;
 
 public SplashScreenAsyncTask(Activity parentActivity, ProgressBar bar) {
  // TODO Auto-generated constructor stub
  super();
  Log.i(TAG, "SplashScreenAsyncTask().");
  mParentActivity = parentActivity;
  spinTask = bar;
 }
 
 @Override
 protected String doInBackground(URL... params) {
  // TODO Auto-generated method stub
  int progress = 0;
  while(progress<=waitnumber) {
   try {
    Thread.sleep(500);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   progress++;
  }
  return doInReturn;
 }

 @Override
 protected void onPreExecute() {
  // TODO Auto-generated method stub
  super.onPreExecute();
  Log.i(TAG, "onPreExecute().");
  spinTask.setVisibility(View.VISIBLE);
 }
 
 @Override
 protected void onProgressUpdate(Integer... values) {
  // TODO Auto-generated method stub
  super.onProgressUpdate(values);
 }
 
 @Override
 protected void onPostExecute(String result) {
  // TODO Auto-generated method stub
  super.onPostExecute(result);
  Log.i(TAG, "onPostExecute().");
  spinTask.setVisibility(View.GONE);
  Intent intent = new Intent();
  intent.setClass(mParentActivity, MainActivity.class);
  mParentActivity.startActivity(intent);
 }
}

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.splashscreen"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            
        </activity>
        <activity
            android:name="com.example.splashscreen.SplashScreenActivity"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Black.NoTitleBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

GitHub SplashScreen

四、執行結果


沒有留言:

張貼留言