標準 List 功能薄弱,無 Model/View 分離。本文實作繼承 List 的 ExpandList,支援兩層可伸縮樹結構、標籤/數據分離、激活/非激活圖示切換、選擇事件精準回傳任意 Object、資料結構無關性。
label:顯示文字type:GROUP=1(父節點,content 為子節點 Vector)或 ITEM=0(葉節點)imagePath / selectImgPath:預設/選中圖示路徑ifselected:是否展開(父節點)或高亮(葉節點)content:任意 Object 業務數據itemList:完整資料樹(Vector<ExpandListItem>)appearHookList:當前螢幕實際顯示的扁平化列表(含縮進空格)currentSelectedIndex/Object:快速定位選中項itemList,呼叫 LoadList()。LoadList() 先清空 List,遞迴遍歷 itemList:ifselected=true 則遞迴加入所有子節點(縮進一空格),圖示切換為 selectImgPath。appearHookList 保持索引對應。commandAction 取得 List 選中索引,對應 appearHookList 找到真實 ExpandListItem。ifselected,重新 LoadList() 刷新(簡單但效率較低,可優化為動態插入/移除子節點)。selectImgPath 則更新圖示,回傳 content 給上層業務邏輯。public class ExpandList extends List implements CommandListener {
private Vector itemList = new Vector();
private Vector appearHookList = new Vector();
// ... 建構子、appendItem、Init、LoadList 詳見原文
public void commandAction(Command c, Displayable d) {
int idx = getSelectedIndex();
if (idx >= 0 && idx < appearHookList.size()) {
ExpandListItem item = (ExpandListItem) appearHookList.elementAt(idx);
if (item.getType() == ExpandListItem.GROUP) {
item.setIfselected(!item.Ifselected());
LoadList(); // 簡單粗暴刷新
} else {
// 葉節點處理:圖示切換、事件回調等
}
}
}
}
效果圖:

註:究極方案仍是自繪 Canvas,但繼承 List 可快速產出可用原型。