// 在 onCreate() 中初始化 View
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.fragment_xxx, null); // 錯誤:無 container
mTextView = view.findViewById(R.id.tv); // 這裡能找到
}
// 在其他方法(如 onClick)中使用 mTextView → NullPointerException
Fragment 的 View 層級生命周期與 Activity 不同。
onCreate():Fragment 實例創建,**View 尚未創建**。onCreateView():負責 **inflater 布局並返回 View 實例**。onViewCreated():View **已創建完成**,可安全 findViewById。onDestroyView():View **被銷毀**,引用失效,需置空防洩漏。public class MyFragment extends Fragment {
private TextView mTextView; // 成員變量持有引用
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
// 1. 僅負責 inflate,不做 findViewById
return inflater.inflate(R.layout.fragment_xxx, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// 2. 在這裡安全初始化所有 View
mTextView = view.findViewById(R.id.tv);
mRecyclerView = view.findViewById(R.id.rv);
// 3. 設置監聽、適配器等
initListeners();
loadData();
}
@Override
public void onDestroyView() {
super.onDestroyView();
// 4. 釋放 View 引用,防止內存洩漏
mTextView = null;
mRecyclerView = null;
}
}
| 錯誤做法 | 後果 |
|---|---|
| 在 onCreate() inflate 並 findView | View 未附加到容器,布局參數失效;旋轉屏幕後引用失效。 |
| 在 onCreateView() 直接 findView | 雖可行,但職責不清;官方推薦分離 inflate 與初始化。 |
| 不在 onDestroyView() 置空 | Fragment 實例可能被復用,舊 View 引用導致內存洩漏或崩潰。 |
// build.gradle 开启 viewBinding
private FragmentXxxBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentXxxBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
binding.tv.setText("Hello");
binding.rv.setAdapter(adapter);
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null; // 一行釋放所有 View 引用
}
遵循 Fragment View 生命周期,**在 onViewCreated 初始化,在 onDestroyView 釋放**,是避免「找不到 View」與內存洩漏的鐵律。