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

Android Fragment 跳轉 Activity 並返回原 Fragment 傳值完整指南

     編輯:程式設計綜合問答

場景

Fragment A → 啟動 Activity B → B 完成後返回 Fragment A 並攜帶資料。

核心機制

  • Fragment 依附於 Activity,生命週期由宿主 Activity 管理。
  • Fragment 可呼叫 getActivity().startActivityForResult()(API < 30)或 registerForActivityResult()(現代 API)。
  • 結果由宿主 Activity 的 onActivityResult() 接收,再轉發給 Fragment。

現代寫法:Activity Result API (AndroidX Activity 1.2+)

// Fragment 內
private final ActivityResultLauncher<Intent> launcher = registerForActivityResult(
    new ActivityResultContracts.StartActivityForResult(),
    result -> {
        if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
            String data = result.getData().getStringExtra("key");
            // 更新 UI / 處理資料
        }
    }
);

void openActivityB() {
    Intent intent = new Intent(requireContext(), ActivityB.class);
    launcher.launch(intent);
}

傳統寫法:startActivityForResult + 宿主轉發

// Fragment
void openActivityB() {
    Intent intent = new Intent(getActivity(), ActivityB.class);
    startActivityForResult(intent, REQUEST_CODE_B); // Fragment 自己的 requestCode
}

// Fragment 覆寫 onActivityResult (需宿主 Activity 也覆寫並轉發)
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_B && resultCode == Activity.RESULT_OK) {
        String value = data.getStringExtra("key");
    }
}

// 宿主 Activity (關鍵:必須轉發)
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    // 讓 FragmentManager 分發給對應 Fragment
    // FragmentManager 會自動根據 requestCode 高位分發,無需手動轉發 (API 28+)
    // 早期版本需手動遍歷 fragments 呼叫 onActivityResult
}

Activity B 返回資料

// ActivityB
void finishWithResult(String value) {
    Intent result = new Intent();
    result.putExtra("key", value);
    setResult(Activity.RESULT_OK, result);
    finish();
}

注意事項

  • Fragment 的 requestCode 僅 16 位:startActivityForResult 時,Fragment 會將 requestCode 高 16 位編碼 Fragment 識別碼,低 16 位為使用者代碼。自定義 code 需 < 0xFFFF。
  • Fragment 重建:若宿主 Activity 因配置變更重建,Fragment 也會重建,launcher 需在 onCreate 註冊以保證存活。
  • 不要在 Fragment 用 startActivityForResult 後直接呼叫 getActivity().startActivityForResult,會導致雙重包裝 requestCode 錯誤。
  • 大數據傳遞:避免放在 Intent Extra (Binder 限制 ~1MB),改用 ViewModel (共享於 Activity 與 Fragment) 或檔案/資料庫。

最佳實踐:共享 ViewModel

// SharedViewModel (Scoped to Activity)
class SharedViewModel : ViewModel() {
    val resultData = MutableLiveData<String>()
}

// Fragment A
val model = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
model.resultData.observe(getViewLifecycleOwner(), { data -> /* 更新 UI */ })

// Activity B
val model = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
model.resultData.postValue("從 B 返回的資料")
finish()

此法完全解耦 Fragment/Activity,生命週期感知,支援配置變更存活。

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