整体架构分析
一个典型的 组合式UI架构 ,使用了 Slot API 设计模式。图表示意:
MediaItemLayout (核心布局容器)
├── 参数:
│ ├── leading: () -> Unit // 左侧内容
│ ├── center: () -> Unit // 中间内容
│ └── trailing: () -> Unit // 右侧内容(可选)
│
├── 内部结构:
│ ├── Row (水平布局)
│ │ ├── leading() // 左侧
│ │ ├── center() // 中间(有weight=1)
│ │ └── trailing() // 右侧
│ └── HorizontalDivider // 分割线
│
└── 两种具体实现:
├── MediaItemNormal // 普通样式:封面 + 标题/副标题
└── MediaItemWithIndex // 带序号样式:序号 + 封面 + 标题/副标题 + 时长
详细解析
1. 核心布局组件:MediaItemLayout
kotlin
@Composable
fun MediaItemLayout(
modifier: Modifier = Modifier,
leading: @Composable () -> Unit, // 左侧插槽
center: @Composable () -> Unit, // 中间插槽
trailing: (@Composable () -> Unit)? = null, // 右侧插槽(可选)
showDivider: Boolean = true
)
这是一个 布局容器组件,特点:
- Slot API 设计:通过函数参数接收内容
- 可复用性强:同样的布局可以展示不同内容
- 灵活配置:可以选择是否显示分割线、是否显示右侧内容
2. 两种具体实现
A. MediaItemNormal - 普通媒体项
[ 封面图片 ] [ 标题 ]
[ 副标题 ]
用于:播放列表、专辑列表等不需要序号的地方
B. MediaItemWithIndex - 带序号媒体项
[ 01 ] [ 封面图片 ] [ 标题 ] [ 3:45 ]
[ 副标题 ]
用于:歌曲列表、播客列表等需要显示序号和时长的场景
3. 子组件分工
| 组件 | 功能 | 备注 |
|---|---|---|
IndexBox |
显示序号/播放动画 | 选中时显示音乐波动画 |
CoverBox |
显示封面图片 | 可显示播放动画 |
TitleSubtitleColumn |
标题和副标题 | 垂直排列,支持省略 |
DurationText |
显示时长 | 格式化时间显示 |
数据流
MediaItemUiModel (数据模型)
├── imageSrc → CoverBox
├── title → TitleSubtitleColumn
├── subTitle → TitleSubtitleColumn
├── index → IndexBox (仅MediaItemWithIndex)
└── duration → DurationText (仅MediaItemWithIndex)
设计模式优势
1. 开闭原则
- 新增样式只需创建新的组合函数
- 不需要修改
MediaItemLayout
2. 单一职责
- 每个组件只做一件事
MediaItemLayout只负责布局CoverBox只负责封面显示TitleSubtitleColumn只负责文字显示
3. Slot API 优势
kotlin
// 可以轻松创建新的变体
@Composable
fun MediaItemWithAction(
uiModel: MediaItemUiModel,
onActionClick: () -> Unit
) {
MediaItemLayout(
leading = { CoverBox(...) },
center = { TitleSubtitleColumn(...) },
trailing = {
IconButton(onClick = onActionClick) {
Icon(Icons.Default.MoreVert, "更多")
}
}
)
}
使用示例
kotlin
// 普通样式
MediaItemNormal(
uiModel = MediaItemUiModel(
imageSrc = "album_cover_url",
title = "Song Title",
subTitle = "Artist Name"
),
isSelected = false,
isPlaying = false
)
// 带序号样式
MediaItemWithIndex(
uiModel = MediaItemUiModel(
imageSrc = "album_cover_url",
title = "Song Title",
subTitle = "Artist Name",
index = 5, // 显示 "06"
duration = 225000 // 显示 "3:45"
),
isSelected = true, // 显示播放动画
isPlaying = true // 动画播放状态
)
总结
这个文件展示了 优秀的Compose架构设计:
MediaItemLayout是核心:作为布局容器,定义了整体的三栏结构- Slot API 提供灵活性:通过函数参数接收内容,支持多种变体
- 函数组合实现复用:小组件可以独立使用,也可以组合成复杂组件
- 数据驱动UI :
MediaItemUiModel包含所有显示数据 - 状态驱动交互 :通过
isSelected、isPlaying控制UI状态
这种设计让代码:
- ✅ 易于维护:每个组件职责清晰
- ✅ 易于扩展:添加新样式很简单
- ✅ 易于测试:组件可以独立测试
- ✅ 易于理解:逻辑分层清晰