在 Fragment 架構的登入流程中:Fragment A(帳號輸入)→ Fragment/Activity B(密碼輸入)→ 登入成功 → 需通知 Fragment A 更新頭像/狀態。推薦三種主流方案:
// Fragment A 註冊
LocalBroadcastManager.getInstance(requireContext())
.registerReceiver(loginReceiver, new IntentFilter("LOGIN_SUCCESS"));
// 登入頁面發送
Intent intent = new Intent("LOGIN_SUCCESS");
intent.putExtra("avatarUrl", url);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
// Fragment A 接收
private BroadcastReceiver loginReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String url = intent.getStringExtra("avatarUrl");
updateAvatar(url);
}
};
@Override
public void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(requireContext()).unregisterReceiver(loginReceiver);
}
// SharedViewModel.kt
class SharedViewModel : ViewModel() {
val loginResult = MutableLiveData()
}
// Fragment A 觀察
viewModel.loginResult.observe(getViewLifecycleOwner(), result -> {
updateAvatar(result.avatarUrl);
});
// 登入頁面設定
viewModel.loginResult.postValue(new LoginResult(avatarUrl));
// 登入 Fragment (B) 設定結果
getParentFragmentManager().setFragmentResult("login_request", bundleOf("avatarUrl" to url))
// Fragment A 監聽
getParentFragmentManager().setFragmentResultListener("login_request", this, { _, bundle ->
val url = bundle.getString("avatarUrl")
updateAvatar(url)
})
| 方案 | 優點 | 適用場景 |
|---|---|---|
| LocalBroadcast | 簡單、跨 Activity/Service | 舊專案、需跨進程通訊 |
| SharedViewModel | 生命週期安全、資料集中、易測試 | 現代 MVVM 架構、多 Fragment 共享狀態 |
| Fragment Result | 輕量、無額外依賴、型別安全 | 單純 Fragment 間回傳資料 |
若專案已導入 ViewModel,**方案二最佳**;若輕量需求,**方案三最簡潔**。