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

Android Fragment getArguments() 回傳 null 解決:new Fragment() 重複建立實例

     編輯:程式設計綜合問答

問題現象

Fragment 中呼叫 getArguments() 回傳 null,導致無法接收傳遞的 Bundle 參數。

錯誤代碼分析


private void updateTab(String tabId, int placeholder) {
    FragmentManager fm = getFragmentManager();
    if (fm.findFragmentByTag(tabId) == null) {
        Bundle arguments = new Bundle();
        arguments.putInt("current_day", mCurrentTab);
        
        EpgEventListFragment fragment = new EpgEventListFragment();
        fragment.setArguments(arguments); // 設定參數給 fragment 實例 A
        
        // 錯誤:這裡又 new 了一個新實例 B,實例 A 被丟棄!
        fm.beginTransaction()
          .replace(placeholder, new EpgEventListFragment(), tabId) // 實例 B 無參數
          .commit();
    }
}

核心錯誤:建立了兩個 Fragment 實例,setArguments 設定給第一個,但 replace() 放入的是第二個 (無參數)。

正確代碼


private void updateTab(String tabId, int placeholder) {
    FragmentManager fm = getFragmentManager();
    if (fm.findFragmentByTag(tabId) == null) {
        Bundle arguments = new Bundle();
        arguments.putInt("current_day", mCurrentTab);
        
        EpgEventListFragment fragment = new EpgEventListFragment();
        fragment.setArguments(arguments); // 設定參數
        
        // 修正:使用同一個已設定參數的實例
        fm.beginTransaction()
          .replace(placeholder, fragment, tabId) // 放入 fragment 實例 A
          .commit();
    }
}

Fragment 參數傳遞最佳實踐


// 1. 靜態工廠方法 (推薦) - 封裝建立邏輯
public static EpgEventListFragment newInstance(int currentDay) {
    EpgEventListFragment fragment = new EpgEventListFragment();
    Bundle args = new Bundle();
    args.putInt("current_day", currentDay);
    fragment.setArguments(args);
    return fragment;
}

// 使用方式
Fragment fragment = EpgEventListFragment.newInstance(mCurrentTab);
fm.beginTransaction().replace(R.id.container, fragment, "tag").commit();

// 2. 在 Fragment 中安全取得參數
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bundle args = getArguments();
    if (args != null) {
        mCurrentDay = args.getInt("current_day", 0); // 提供預設值
    } else {
        // 防禦性處理:從 Activity 取得、或設定預設值
        mCurrentDay = 0;
    }
}

常見陷阱

情況結果解決
Fragment 重建 (旋轉螢幕)參數保留 (Bundle 隨 Fragment 保存)無需額外處理
用 new Fragment() 而非工廠方法易忘記 setArguments強制使用 newInstance()
在 onAttach/onCreateView 取參數getArguments() 同樣可用建議在 onCreate 取得
巢狀 Fragment用 getChildFragmentManager()注意 FragmentManager 選擇

現代 Navigation Component 寫法


// navigation_graph.xml

    


// 程式碼導航 (自動處理 Bundle)
NavController nav = Navigation.findNavController(this, R.id.nav_host);
Bundle args = new Bundle();
args.putInt("current_day", mCurrentTab);
nav.navigate(R.id.epgFragment, args);

// Fragment 中取得 (Type-safe)
int day = EpgFragmentArgs.fromBundle(getArguments()).getCurrentDay();
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved