You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Jetpack Compose和Material 3实现带模糊透明背景的Fragment加载器

Jetpack Compose无View架构下的Fragment叠加加载方案

可行性结论

完全可行,借助Fragment的栈管理、透明主题配置,配合Compose的模糊背景和自定义动画,能完美实现你要的叠加加载流程。

具体实现步骤

1. 配置透明模糊背景

  • 给Fragment2、Fragment3设置透明主题,在AndroidManifest.xml里对应Fragment的声明中指定:
    <activity
        android:name=".MainActivity"
        ...>
        <fragment
            android:name=".Fragment2"
            android:theme="@style/TransparentBlurTheme"/>
        <fragment
            android:name=".Fragment3"
            android:theme="@style/TransparentBlurTheme"/>
    </activity>
    
    对应的主题样式:
    <style name="TransparentBlurTheme" parent="Theme.Material3.DayNight.NoActionBar">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item>
    </style>
    
  • 在Compose中给加载器根布局添加模糊遮罩:
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(
                color = Color.Black.copy(alpha = 0.3f),
                brush = Brush.blur(radius = 8.dp)
            )
    ) {
        // 加载动画组件
        CustomLoader()
    }
    

2. 抽离通用加载动画组件

因为Fragment2和Fragment3用相同的加载器,直接写个可复用的Compose函数:

@Composable
fun CustomLoader() {
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        CircularProgressIndicator(
            color = Color.White,
            strokeWidth = 4.dp,
            modifier = Modifier.size(60.dp)
        )
        Spacer(modifier = Modifier.height(16.dp))
        Text(text = "处理中...", color = Color.White)
    }
}

3. Fragment栈管理与流程控制

所有Fragment都用ComposeView承载Compose内容(无View架构下Fragment仍需通过ComposeView挂载Compose树):

  • Fragment1(主UI):
    class Fragment1 : Fragment() {
        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View {
            return ComposeView(requireContext()).apply {
                setContent {
                    // 这里写你的完整主UI
                    Scaffold(topBar = { TopAppBar(title = { Text("主页面") }) }) { padding ->
                        Button(
                            onClick = {
                                // 启动Fragment2,加入栈
                                parentFragmentManager.beginTransaction()
                                    .add(R.id.fragment_container, Fragment2())
                                    .addToBackStack(null)
                                    .commit()
                            },
                            modifier = Modifier.padding(padding)
                        ) {
                            Text("开始处理")
                        }
                    }
                }
            }
        }
    }
    
  • Fragment2(第一个加载器):
    class Fragment2 : Fragment() {
        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View {
            return ComposeView(requireContext()).apply {
                setContent {
                    // 透明模糊背景+加载动画
                    Box(
                        modifier = Modifier
                            .fillMaxSize()
                            .background(
                                color = Color.Black.copy(alpha = 0.3f),
                                brush = Brush.blur(radius = 8.dp)
                            )
                    ) {
                        CustomLoader()
                    }
                }
            }
        }
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            // 模拟计算任务,替换成你的实际业务逻辑
            lifecycleScope.launch {
                delay(2000)
                // 替换当前栈中的Fragment2为Fragment3
                parentFragmentManager.beginTransaction()
                    .replace(R.id.fragment_container, Fragment3())
                    .addToBackStack(null)
                    .commit()
            }
        }
    }
    
  • Fragment3(第二个加载器):
    class Fragment3 : Fragment() {
        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View {
            return ComposeView(requireContext()).apply {
                setContent {
                    // 同样的透明模糊背景+加载动画
                    Box(
                        modifier = Modifier
                            .fillMaxSize()
                            .background(
                                color = Color.Black.copy(alpha = 0.3f),
                                brush = Brush.blur(radius = 8.dp)
                            )
                    ) {
                        CustomLoader()
                    }
                }
            }
        }
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            lifecycleScope.launch {
                delay(2000) // 实际计算逻辑
                // 弹出栈中所有加载Fragment,回到Fragment1
                parentFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
            }
        }
    }
    

4. 关键注意点

  • 确保Fragment容器(R.id.fragment_container)是FrameLayout或其他支持视图叠加的布局,否则加载Fragment无法覆盖主UI。
  • 所有计算任务必须放在协程或后台线程,别阻塞UI线程导致卡顿。
  • 如果需要在加载完成后给Fragment1传递数据,用FragmentResultAPI或者共享ViewModel实现。

内容的提问来源于stack exchange,提问作者Coder123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 03:17:02