雖然 Alert 可用 setTimeout 並搭配 display.setCurrent(alert, nextScreen) 實現簡易啟動畫面,但實測缺點明顯:
Canvas + Timer 方案提供完全可控的視覺呈現與交互邏輯。
import javax.microedition.lcdui.*;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
public class WelcomeCanvas extends Canvas {
private Display display;
private Displayable nextScreen; // 跳轉目標
private Timer timer = new Timer();
private long displayTime = 3000; // 預設 3 秒
private Image splashImage; // 快取圖片避免重複載入
public WelcomeCanvas(Display display, Displayable nextScreen) {
this.display = display;
this.nextScreen = nextScreen;
loadImage();
}
private void loadImage() {
try {
// 圖片放在 /res 或 src 根目錄,打包進 JAR
splashImage = Image.createImage("/splash.png");
} catch (IOException e) {
// 圖片載入失敗時備用:繪製純色背景 + 文字
splashImage = null;
}
}
// 設定顯示毫秒數
public void setDisplayTime(long ms) {
this.displayTime = ms;
}
// Canvas 顯示時啟動計時器
protected void showNotify() {
timer.schedule(new TimerTask() {
public void run() {
dismiss();
}
}, displayTime);
}
// 繪製邏輯:置中顯示圖片,支援雙緩衝
protected void paint(Graphics g) {
int w = getWidth(), h = getHeight();
g.setColor(0xFFFFFF); // 白底
g.fillRect(0, 0, w, h);
if (splashImage != null) {
// 置中繪製
g.drawImage(splashImage, w / 2, h / 2, Graphics.HCENTER | Graphics.VCENTER);
} else {
// 文字備用
g.setColor(0x000000);
g.drawString("Loading...", w / 2, h / 2, Graphics.HCENTER | Graphics.BOTTOM);
}
}
// 任意按鍵觸發跳過
protected void keyPressed(int keyCode) {
dismiss();
}
// 觸控螢幕支援
protected void pointerPressed(int x, int y) {
dismiss();
}
// 統一跳轉邏輯:取消計時器、切換畫面
private void dismiss() {
timer.cancel();
display.setCurrent(nextScreen);
}
}
public class MyMIDlet extends MIDlet {
private Display display;
private Form mainForm;
protected void startApp() {
if (display == null) {
display = Display.getDisplay(this);
mainForm = new Form("主功能選單");
mainForm.append("歡迎進入主程式!");
// 可在這裡加入 List、TextBox 等真實功能畫面
}
WelcomeCanvas welcome = new WelcomeCanvas(display, mainForm);
welcome.setDisplayTime(6000); // 6 秒品牌曝光
display.setCurrent(welcome);
}
protected void pauseApp() {}
protected void destroyApp(boolean unconditional) {}
}
若需播放幀動畫 (參考系列文章「基於 MIDP 1.0 實現動畫效果」),可在 WelcomeCanvas 中整合 AnimatedImage:
// 在 WelcomeCanvas 增加欄位
private AnimatedImage animation;
// 建構子載入動畫幀
Image[] frames = new Image[7];
for (int i = 0; i < 7; i++) {
frames[i] = Image.createImage("/anim/bird" + i + ".png");
}
animation = new AnimatedImage(this, frames); // 繼承自 TimerTask
animation.move(20, 20);
// showNotify 改為同時啟動動畫 Timer
timer.schedule(animation, 0, 100); // 每 100ms 換幀
timer.schedule(new TimerTask() { public void run() { dismiss(); } }, displayTime);
// paint 方法中繪製動畫
protected void paint(Graphics g) {
// ... 背景清除 ...
if (animation != null) animation.draw(g);
}
| 項目 | 建議 |
|---|---|
| 圖片尺寸 | 建議 ≤ 螢幕解析度 (如 240x320),單檔 < 20KB,總資源 < 50KB 以免 JAR 過大。 |
| 圖片格式 | PNG (無損、支援透明) 或 JPEG (照片類)。 |
| 顯示時長 | 3-5 秒最佳;過長引起用戶不耐,過短品牌曝光不足。 |
| 資源載入 | 在 WelcomeCanvas 建構子預載圖片,避免首次 paint 卡頓。 |
| 雙緩衝 | 若 isDoubleBuffered() 為 false,參考「雙緩衝技術」文章自行實作離屏繪圖。 |
| 記憶體釋放 | dismiss() 後可將 splashImage = null、animation = null 協助 GC。 |