为什么作者需要在 Compose 中一遍又一遍地传递参数 Modifier 呢?

Why does the author need to pass the paramter Modifier again and again in Compose ?

以下代码A来自官方样本project.

参数Modifier在代码A的函数中反复传递

我完全不明白为什么作者要设计在函数之间反复传递参数Modifier

我觉得Code B很简单。 Code A的设计框架会得到什么好处?

代码A

@AndroidEntryPoint
class DetailsActivity : ComponentActivity() {
    ...
        DetailsScreen(
            onErrorLoading = { finish() },
            modifier = Modifier
               .statusBarsPadding()
               .navigationBarsPadding()
       )
    ...
}

@Composable
fun DetailsScreen(
    onErrorLoading: () -> Unit,
    modifier: Modifier = Modifier,
    viewModel: DetailsViewModel = viewModel()
) {
    ...
     DetailsContent(cityDetails.data, modifier.fillMaxSize())
     ..
}


@Composable
fun DetailsContent(
    exploreModel: ExploreModel,
    modifier: Modifier = Modifier
) {
    Column(modifier = modifier, verticalArrangement = Arrangement.Center) {
       ...
    }
}

代码B

@AndroidEntryPoint
class DetailsActivity : ComponentActivity() {
    ...
        DetailsScreen(
            onErrorLoading = { finish() }           
       )
    ...
}

@Composable
fun DetailsScreen(
    onErrorLoading: () -> Unit,   
    viewModel: DetailsViewModel = viewModel()
) {
    ...
     DetailsContent(cityDetails.data)
     ..
}


@Composable
fun DetailsContent(
    exploreModel: ExploreModel    
) {
   val  modifier = Modifier
            .statusBarsPadding()
            .navigationBarsPadding()
            .fillMaxSize()

    Column(modifier = modifier, verticalArrangement = Arrangement.Center) {
       ...
    }
}

statusBarsPadding()navigationBarsPadding() 事实上,任何其他修饰符都必须在其相关功能中添加。

在上面的代码B中,假设DetailsActivityBottomNavigationBar。 现在必须将 BottomNavigationBar 填充添加到 DetailsScreen.

当我们有更多可组合函数或将来可以更改为其他函数时,并非总是可以将所有修饰符添加到 DetailsContent(从上面的代码)。

当我们在每个级别都有修改器时,维护会很容易。

使用 Jetpack Compose 时,最好尝试创建无状态的 re-usable 视图。使可组合视图更 re-usable 的方法之一是为其提供 Modifier.

的参数

使用 代码 B,您现在已经通过在层次结构中的最低视图上定义修饰符元素来确定 DetailsContent 应该如何显示。这意味着,如果有另一个可组合视图需要以不同的方式使用 DetailsContent,则该其他视图将无法覆盖 DetailsContent 中的修饰符! (例如,如果另一个视图不需要 DetailsContentfillMaxSixe()? 怎么办)

使用 代码 A,层次结构中较低的视图从其父级继承修饰符。这允许更大的灵活性,并且 re-usability 让父级决定如何显示子级可组合项的内容。

this layouts codelab 中所述:

Most composables accept an optional modifier parameter to make them more flexible, enabling the caller to modify them. If you're creating your own composable, consider having a modifier as a parameter, default it to Modifier (i.e. empty modifier that doesn't do anything) and apply it to the root composable of your function.

我有写一个Composable函数的习惯,传递Modifier参数,在最外层的composable中引用它function.like this

@Composable
fun Simple(modifier: Modifier = Modifier) {
    Box(modifier){
        //...
    }
}

您可以将每个可组合项视为一个 activity 或片段,通过可以是 activity 或片段的修饰符进行处理。大大提高了可重用性!