架構圖解
Activity (MainActivity)
├─ DrawerLayout
│ ├─ ListView (id: lv) ← 左側選單
│ └─ FrameLayout (id: fm) ← 內容容器,動態替換 Fragment
└─ FragmentManager + FragmentTransaction 管理切換
關鍵代碼片段
1. 主 Activity 綁定 ListView 點擊
lv.setOnItemClickListener((parent, view, position, id) -> {
Fragment target = null;
switch (position) {
case 0: target = new PieChartFragment(); break; // 餅圖
case 1: target = new StaticLineFragment(); break; // 靜態折線
case 3: target = new WebFragment(); break; // Web
// 其他 case...
}
if (target != null) {
getFragmentManager().beginTransaction()
.replace(R.id.fm, target)
.commit();
drawerLayout.closeDrawer(Gravity.START); // 關閉抽屜
}
});
2. Fragment 內部正確獲取 View
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_web, container, false); // 傳 false,不立即附加
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// 在這裡 findViewById,不要在 onActivityCreated 裡用 getActivity().findViewById
Button btn = view.findViewById(R.id.webbut);
webView = view.findViewById(R.id.webweb);
// 設定 WebView、點擊事件...
}
常見坑點與修正
| 錯誤做法 | 後果 | 正確做法 |
在 Fragment 用 getActivity().setContentView() | 覆蓋整個 Activity 佈局,導致 DrawerLayout 消失 | 只在 onCreateView inflate 自己的布局 |
ListView 設定 android:choiceMode="singleChoice" 但未高亮 | 視覺無反饋 | 配合 listView.setItemChecked(position, true) + selector 背景 |
WebFragment 內部重複 setWebViewClient | 頁面跳轉異常 | 在 onViewCreated 設定一次即可 |
完整專案結構建議
- 每個功能一個 Fragment 類(PieChartFragment、WebFragment 等)。
- 共用 BaseFragment 封裝通用邏輯(ToolBar、載入狀態)。
- 使用
FragmentFactory 或簡單 Map 管理位置→Fragment 映射,避免巨大 switch。