核心概念
父 Fragment 內嵌套子 Fragment 時,**必須使用 `getChildFragmentManager()`** 而非 `getFragmentManager()` (已棄用) 或 `getActivity().getSupportFragmentManager()`。子 Fragment 的生命週期由父 Fragment 管理,隨父 Fragment 銷毀而銷毀。
完整實現步驟
1. 父 Fragment 布局預留容器
```xml
```
2. 父 Fragment 代碼動態添加子 Fragment
```java
public class ParentFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_parent, container, false);
// 關鍵:使用 getChildFragmentManager()
if (savedInstanceState == null) { // 防止重疊
getChildFragmentManager().beginTransaction()
.replace(R.id.child_container, new ChildFragment())
.commit();
}
return view;
}
}
```
3. 子 Fragment 正常實現
```java
public class ChildFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_child, container, false);
}
}
```
關鍵注意事項
| 場景 | 正確做法 | 錯誤做法 |
| 獲取 FragmentManager |
`getChildFragmentManager()` |
`getActivity().getSupportFragmentManager()` (會加到 Activity 根容器) |
| 嵌套層級 > 2 |
每層都用各自的 `getChildFragmentManager()` |
跨層級混用 Manager |
| ViewPager + Fragment |
`FragmentStateAdapter` (AndroidX) 內部自動用 `getChildFragmentManager()` |
手動用 Activity Manager 導致狀態丟失 |
| 保存狀態 |
子 Fragment 自動隨父 Fragment 保存/恢復 (需調用 super.onSaveInstanceState) |
手動管理子 Fragment 狀態 |
| 彈出回棧 |
`getChildFragmentManager().popBackStack()` |
`getActivity().onBackPressed()` 影響整個 Activity |
XML 靜態聲明嵌套 (API 17+)
```xml
```
*注意:靜態嵌套無法動態替換,且子 Fragment 不能再包含 `
` 標籤 (需動態添加)。*
常見崩潰與解決
IllegalStateException: Fragment already added:`onCreateView` 多次調用未判斷 `savedInstanceState`,添加 `if (savedInstanceState == null)` 守衛。
FragmentManager is already executing transactions:在 `onAttach`/`onCreate` 中提交事務,移至 `onCreateView` 或 `onViewCreated`。
- 子 Fragment `getActivity()` 返回 null:確保父 Fragment 已附加到 Activity,子 Fragment 生命週期正確。
現代化替代方案:Navigation Component
使用 `navigation.xml` 定義巢狀導航圖 (`` 嵌套 ``),配合 ``,框架自動處理 `getChildFragmentManager()`、返回棧、深層鏈接、動畫,極大簡化代碼。