在做Android開發的時候,有時候需要在一個Activity的裏面調用兩次setContentView方法。比如在應用啓動的時候,開始顯示歡迎界面,在顯示歡迎界面的同時,進行後臺數據的處理,等到後臺數據準備好了,才顯示真正的應用界面。這樣的做法不會讓使用者有突兀的感覺。反之,應用已啓動就顯示真正的應用界面,但在後續的操作需要準備數據的時候,假定是5秒鐘,那麼在這5秒鐘內使用者將無法使用該應用,這樣用戶界面顯然是不夠友好的。
爲了實現歡迎界面,大家很自然地就會想到:在onCreate方法中,調用兩次setContentView。是的,要調用兩次setContentView,但怎麼調用還是有點技巧,而不是簡單地調用兩次setContentView就可以解決問題的。下面,我們就用實際的例子來給予說明。
1. 在Eclipse中,先如下創建一個項目:
2. 將圖片mm.png拷貝到項目的res/drawable-mdpi文件夾下,這個圖片將用作歡迎界面。mm.png的圖片是這樣的:
3. 修改原項目的main.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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="40dip"
android:textColor="#FFFF00"
android:text="This is the real application interface!"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="OK"
/>
</LinearLayout>
4. 再增加一個佈局文件welcome.xml,用做歡迎界面。編輯該文件,使其內容如下:
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
android:src="@drawable/mm"
/>
</LinearLayout>
很顯然,這個歡迎界面就是顯示步驟2增加的圖片mm.png
5. 下面來完善WelcomeActivity.java的代碼,如果我們像下面這樣直接寫:
package com.pat.welcome;
import android.app.Activity;
import android.os.Bundle;
public class WelcomeActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.main); // 把這一句改爲下面一句,用以顯示歡迎界面
setContentView(R.layout.welcome);
// 下面是模擬數據處理需要5秒鐘的時間
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
setContentView(R.layout.main); // 顯示真正的應用界面
}
}
你將會發現,歡迎界面根本沒有出現。在本該出現歡迎界面的時候,界面上什麼也沒有,過了幾秒鐘(程序中指定的5秒鐘),然後就直接顯示:
如果把上面程序中的兩條setContentView語句的位置互換,程序開始運行的時候界面上什麼也沒有,過了幾秒鐘(程序中指定的5秒鐘),然後就直接顯示歡迎界面:
從現象上看,似乎只有最後那個setContentView語句纔會起作用。事實上,的確是這樣的。setContentView方法所指定的View,只有在onCreate方法返回後纔會顯示在界面上。因此,如果調用了兩次setContentView方法,只有最後一次纔是有效的。
6. 那麼怎樣解決我們在開始提出的問題呢?即應用啓動的時候,顯示歡迎界面,過幾秒後,再顯示真正的應用程序界面呢?網上給出了幾種界面辦法,但個人認爲都不是什麼好辦法。我在網上所能找到最靠譜的解決辦法是這個帖子中的2樓給出的辦法,其他所看到的辦法基本上都是在誤人,因此特提出下面的解決辦法,供大家參考。這個解決辦法和前面提及的帖子的思路差不多,但應該更簡單一些。具體做法:
第1~4步的工作維持不變,僅將WelcomeActivity.java的代碼修改,使之如下:
package com.pat.welcome;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class WelcomeActivity extends Activity
{
private Handler handler; // 聲明handler
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.main); // 把這一句改爲下面一句
setContentView(R.layout.welcome);
// 初始化handler
handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
if(msg.what == 1) // handler接收到相關的消息後
{
setContentView(R.layout.main); // 顯示真正的應用界面
}
}
};
// 新建一個線程,過5秒鐘後向handler發送一個消息
Runnable runnable = newRunnable()
{
public void run()
{
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
handler.sendEmptyMessage(1);
}
};
Thread thread = new Thread(runnable);
thread.start();
// // 下面是模擬數據處理需要5秒鐘的時間
// try
// {
// Thread.sleep(5000);
// }
// catch (InterruptedException e)
// {
// e.printStackTrace();
// }
//
// setContentView(R.layout.main);
}
}
上面代碼的粗體字部分,均爲修改步驟5中的代碼所增加的。
這樣就可以做到先顯示歡迎界面5秒鐘,然後再顯示真正的應用程序界面。