Fragment
应用基础 · androidx.fragment
Fragment 结果与 Compose 互操作1.9.0-rc01
在 Fragment 间传一次性结果,并在两种 UI 技术之间选择宿主方向。
最后更新 2026-08-01
Fragment Result API:一次性结果
接收方用 requestKey 注册生命周期感知 listener,发送方用同一 key 提交:
// 接收方
parentFragmentManager.setFragmentResultListener(
"pick-user",
viewLifecycleOwner, // 生命周期感知:View 销毁自动移除
) { _, result ->
viewModel.select(result.getString("userId").orEmpty())
}
// 发送方
parentFragmentManager.setFragmentResult(
"pick-user",
bundleOf("userId" to userId),
)要点:
- 结果是 FragmentManager 范围内的一次性交付机制。
- listener 生命周期绑定
viewLifecycleOwner(不是 Fragment lifecycle)。 - 不是共享持续状态——持续状态用共享 ViewModel 或 repository。
方向 1:Compose 放进 Fragment
迁移已有 Fragment 页面时,在 View 中返回 ComposeView:
class SettingsFragment : Fragment() {
private val viewModel: SettingsViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View = ComposeView(requireContext()).apply {
setViewCompositionStrategy(
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
)
setContent {
MaterialTheme {
SettingsScreen(viewModel)
}
}
}
}ViewCompositionStrategy 决定 Composition 何时销毁:
| 策略 | 销毁时机 |
|---|---|
DisposeOnViewTreeLifecycleDestroyed(推荐) | View 树 lifecycle 销毁时 |
DisposeOnDetachedFromWindow | View 分离窗口时 |
DisposeOnViewTreeLifecycleDestroyed + 手动 | 混合 |
方向 2:Fragment 放进 Compose
fragment-compose 提供 AndroidFragment:
@Composable
fun LegacyMapScreen(args: Bundle) {
val fragmentState = rememberFragmentState()
AndroidFragment<LegacyMapFragment>(
fragmentState = fragmentState,
arguments = args,
)
}- 适合无法立即改写的地图、媒体或第三方 Fragment。
- 不应成为新 Compose 页面的默认分层——新页面直接写 Compose。
选择方向
| 场景 | 方向 |
|---|---|
| 已有 Fragment 应用,逐页迁移 | ComposeView 放进 Fragment |
| 必须保留的第三方 Fragment | AndroidFragment 放进 Compose |
| 全新页面 | 纯 Compose,不要 Fragment |
常见陷阱
- Result 非持续状态:把结果存 SharedPreferences 当状态 → 错。
- listener 用 Fragment lifecycle:View 销毁后仍活着 → 泄漏。
- ComposeView 忘策略:Composition 不销毁 → 泄漏。
- AndroidFragment 塞新页面:增加 Fragment 复杂度,无收益。
复制即用
// 在 Fragment 中返回 Compose 内容
override fun onCreateView(...): View = ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent { ProfileScreen(viewModel) }
}
// 在 Compose 中托管 Fragment
@Composable
fun MapScreen() {
AndroidFragment<LegacyMapFragment>(rememberFragmentState())
}要点
- Fragment Result 是 key 配对的一次性交付,生命周期感知。
- ComposeView 进 Fragment:迁移方向;AndroidFragment 进 Compose:托管遗留。
- 新页面纯 Compose;Composition 销毁策略必须设对。