首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android Fragment 中 View 初始化找不到?生命周期錯位解析

     編輯:程式設計綜合問答

典型錯誤現象

// 在 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 並 findViewView 未附加到容器,布局參數失效;旋轉屏幕後引用失效。
在 onCreateView() 直接 findView雖可行,但職責不清;官方推薦分離 inflate 與初始化。
不在 onDestroyView() 置空Fragment 實例可能被復用,舊 View 引用導致內存洩漏或崩潰。

ViewBinding / DataBinding 現代寫法

// 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」與內存洩漏的鐵律。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved