List 組件概覽
javax.microedition.lcdui.List 繼承自 Screen,是高層 UI 中唯一的選單型組件,支援三種選擇模式:
| 模式常量 | 行為 | 典型用途 |
Choice.EXCLUSIVE | 單選 (圓形單選鈕),同一時間僅一項被選中 | 主選單、設定項、性別選擇 |
Choice.MULTIPLE | 多選 (方形核取方塊),可同時選中多項 | 勾選清單、批次操作、興趣標籤 |
Choice.IMPLICIT | 隱式單選 (無指示器),按 FIRE 觸發 CommandListener | 功能選單、遊戲關卡選擇 |
完整實作範例:水果多選清單
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class ListDemo extends MIDlet implements CommandListener {
private List fruitList;
private Command exitCmd, okCmd;
private Display display;
private Alert resultAlert;
public ListDemo() {
// 1. 建立多選清單
fruitList = new List("選擇水果", Choice.MULTIPLE);
fruitList.append("Apple", null); // 文字, 圖示(可為 null)
fruitList.append("Orange", null);
fruitList.append("Banana", null);
// 2. 命令
exitCmd = new Command("離開", Command.EXIT, 1);
okCmd = new Command("確定", Command.OK, 1);
fruitList.addCommand(exitCmd);
fruitList.addCommand(okCmd);
fruitList.setCommandListener(this);
// 3. 結果提示框
resultAlert = new Alert("選擇結果", "", null, AlertType.INFO);
resultAlert.setTimeout(Alert.FOREVER);
}
protected void startApp() {
display = Display.getDisplay(this);
display.setCurrent(fruitList);
}
protected void pauseApp() {}
protected void destroyApp(boolean unconditional) {}
public void commandAction(Command c, Displayable d) {
if (c == exitCmd) {
destroyApp(false);
notifyDestroyed();
} else if (c == okCmd) {
// 讀取多選結果
StringBuffer sb = new StringBuffer("您選擇了: ");
boolean first = true;
for (int i = 0; i < fruitList.size(); i++) {
if (fruitList.isSelected(i)) {
if (!first) sb.append(", ");
sb.append(fruitList.getString(i));
first = false;
}
}
if (first) sb.append("無");
resultAlert.setString(sb.toString());
display.setCurrent(resultAlert, fruitList); // 關閉 Alert 後返回 List
}
}
}
核心 API 速查
| 方法 | 說明 |
append(String, Image) | 新增項目 (圖示可為 null) |
insert(int index, String, Image) | 指定位置插入 |
delete(int index) | 刪除項目 |
set(int index, String, Image) | 修改項目 |
getString(int index) | 取得項目文字 |
getImage(int index) | 取得項目圖示 |
size() | 項目總數 |
isSelected(int index) | 檢查是否被選中 (MULTIPLE/IMPLICIT) |
getSelectedIndex() | 取得單選索引 (EXCLUSIVE/IMPLICIT) |
getSelectedFlags(boolean[]) | 批次取得選中狀態 (MULTIPLE) |
setSelectedFlags(boolean[], boolean) | 批次設定選中狀態 |
setSelectedIndex(int, boolean) | 設定單項選中狀態 |
setFont(int index, Font) | 單獨設定項目字體 |
進階技巧
1. 動態更新清單 (如從網路載入)
// 清空並重建
fruitList.deleteAll(); // MIDP 2.0 新增
// 或逐項刪除
while (fruitList.size() > 0) fruitList.delete(0);
// 批次新增
String[] items = {"Grape", "Pear", "Peach"};
for (String s : items) fruitList.append(s, null);
2. 帶圖示的選單
Image appleIcon = Image.createImage("/res/apple.png");
fruitList.append("Apple", appleIcon);
// 注意:圖示大小建議統一 (如 16x16 或 24x24),否則行高不一致
3. IMPLICIT 模式處理選擇事件
// IMPLICIT 模式下,按 FIRE 鍵不會自動改變選中狀態,
// 需在 CommandListener 中處理
public void commandAction(Command c, Displayable d) {
if (c == List.SELECT_COMMAND) { // 系統隱式 SELECT_COMMAND
int idx = fruitList.getSelectedIndex();
// 執行對應動作...
}
}
常見坑點避雷
- ❌ 忘記
setCommandListener(this) → 按鍵完全無反應。
- ❌ MULTIPLE 模式用
getSelectedIndex() → 永遠返回第一個選中項,應用 isSelected(i) 迴圈或 getSelectedFlags()。
- ❌ 圖示過大導致 OOM → 統一縮放至螢幕高度 10% 以內,或用
setClip 繪製圖集。
- ✅
Alert.setTimeout(Alert.FOREVER) 讓用戶確認後再返回,避免一閃而過。