工作记录

Todo

Process

差不多写完了 timeline screen, 现在改叫 TopicLogScreen. 里面包含了 timeline + composer.

主要处理了下外层捕获事件的问题。

学到一个技巧:

Screen 当做多个 ViewModel 的协调器 如果需要在 ViewModel 之间做一些互操作,那么可以这么做:

  1. 在 ScreenRoute (smart 组件) 里直接注入 2 个 viewModel: Screen(viewModelA, viewModelB)
  2. 利用已有的两个 viewModel,写好交互操作的 action, 传入到需要的地方
  3. 关键点来了:将 2 个 viewModel 对应的 ScreenRoute, 通过 Lambda 函数传给 ScreenContent (dumb 组件),这种方式,也就保证了 ScreenContent 还是可以方便 preview 的!

@Composable
fun TopicLogScreen(
    ...
    timelineViewModel: TimelineViewModel = hiltViewModel(),
    composerViewModel: MessageComposerViewModel = hiltViewModel(),
) {

    val focusManager = LocalFocusManager.current

    val handleComposerDismiss = { // 互操作
        focusManager.clearFocus()
        composerViewModel.clearInputMode()
    }

    TopicLogContent(
        ...
        // ViewModel 对应的组件,这里通过 lambda 传递
        timelineSection = {
            TimelineScreen(
                // 传递互操作
                onTapOutside = handleComposerDismiss,
                onDragList = handleComposerDismiss,
                timelineViewModel = timelineViewModel,
            )
        },
        composerSection = {
            MessageComposer(
                onNavigateBack = onNavigateBack,
                viewModel = composerViewModel,
            )
        },
        handleComposerDismiss = handleComposerDismiss
    )
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TopicLogContent(
    ...
    // 这个 lambda 同样可以接受参数, 所以也可以接受来自 Content 部分的内容
    timelineSection: @Composable () -> Unit,
    composerSection: @Composable () -> Unit,
    // 传递互操作
    handleComposerDismiss: () -> Unit,
) {

  Column() {
    Box(
      modifier = modifier
          .weight(1f)
          .pointerInput(Unit) {
              detectTapGestures {
                  handleComposerDismiss()
              }
          }) {
      timelineSection()
    }
    composerSection()
  }
}

还学到一个原则:子组件在父组件里的布局、动画定义,写到父组件里,子组件定义好自己内部的东西就好了。


生活记录

早上又下了一点雨。


情绪记录

Good

Bad


Reflect