如何将Android Jetpack Compose中重复的DisplayMetrics代码提取到工具类?
几种可行的复用方案
1. Activity扩展函数(简单直接)
直接给Activity写扩展函数,把获取DisplayMetrics的逻辑封装进去,所有Activity都能直接调用,不用重复写原生代码。
// 封装扩展函数到单独的文件(比如DisplayMetricsExtensions.kt) fun Activity.getRealDisplayMetrics(): DisplayMetrics { val dm = DisplayMetrics() windowManager.defaultDisplay.getRealMetrics(dm) return dm } // 在Compose界面中使用 @Composable fun HomeScreen() { val activity = LocalContext.current as Activity val metrics = activity.getRealDisplayMetrics() // 这里写你的计算逻辑,比如获取屏幕宽高 val screenWidth = metrics.widthPixels val screenHeight = metrics.heightPixels }
2. Compose CompositionLocal(全局无感知复用)
如果想在Compose界面里不用每次强转Context为Activity,可以用CompositionLocal把DisplayMetrics全局提供,所有子Composable都能直接获取。
// 定义CompositionLocal(单独文件中) val LocalRealDisplayMetrics = staticCompositionLocalOf<DisplayMetrics> { error("DisplayMetrics 未在父Composable中提供") } // 在Activity中提供实例 class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val dm = DisplayMetrics() windowManager.defaultDisplay.getRealMetrics(dm) setContent { // 全局提供DisplayMetrics CompositionLocalProvider(LocalRealDisplayMetrics provides dm) { MyApp() } } } } // 任意Compose界面中直接使用 @Composable fun ProfileScreen() { val metrics = LocalRealDisplayMetrics.current val density = metrics.density // 执行你的计算逻辑 }
3. 工具类封装(跨场景复用)
如果需要在非Compose代码(比如ViewModel、普通工具类)也复用这套逻辑,可以封装成静态工具类,需要时传入Activity或合法的Context。
object DisplayMetricsHelper { /** * 获取真实屏幕Metrics,需传入Activity实例 */ fun getRealMetrics(activity: Activity): DisplayMetrics { val dm = DisplayMetrics() activity.windowManager.defaultDisplay.getRealMetrics(dm) return dm } /** * 重载方法,接收Context,但必须是Activity的Context */ fun getRealMetrics(context: Context): DisplayMetrics { require(context is Activity) { "传入的Context必须是Activity实例" } return getRealMetrics(context) } } // Compose中使用示例 @Composable fun SettingsScreen() { val context = LocalContext.current // 用remember缓存结果,避免重组重复计算 val metrics = remember { DisplayMetricsHelper.getRealMetrics(context) } // 你的计算逻辑 }
方案选择建议
- 只在Compose+Activity场景复用:优先用扩展函数或CompositionLocal
- 需要跨Compose/非Compose场景复用:选工具类封装
- 追求Compose代码简洁:选CompositionLocal,一次提供全局可用
内容的提问来源于stack exchange,提问作者Ralf Wickum
相关产品推荐
相关产品推荐

