一、功能全景与技术选型
1.1 核心功能模块
- 学习计划创建:支持词库选择、每日学习量设置、开始日期设定(今日/明日)
- 智能周期计算:根据词库总量和每日学习量动态计算预计完成日期
- 多维进度展示:课时进度(学习/练习/测试)、整体完成度环形图
- 计划管理:完整生命周期支持(创建/查看/删除/重建)
1.2 技术架构全景
我们采用经典的三层架构模式,实现了数据层与UI层的完全解耦。这种设计的核心优势在于:业务逻辑的独立演进能力——当需要调整数据源(如从本地存储改为网络请求)时,UI层无需任何修改即可适配。
核心组件交互流程:
- 数据层通过Room数据库持久化学习计划
- Repository作为单一数据源提供响应式数据流
- ViewModel转换数据为UI状态
- Composable组件订阅状态更新
// 分层架构示例
|- data/
|- local/ // Room数据库实体和DAO
|- repository/ // 数据仓库实现
|- ui/
|- plan/
|- components/ // 自定义图表组件
|- viewmodel/ // 状态管理与业务逻辑
|- dialog/ // 对话框组件
二、智能状态管理设计
2.1 分层状态机实现
我们摒弃了传统MVC模式中的分散状态管理,采用类型安全的状态机模型。这种设计的精妙之处体现在:
- 状态穷尽性:通过密封类(Sealed Class)确保所有可能状态都被处理
- 状态隔离性:对话框状态与主界面状态完全分离
- 响应式更新:UI自动响应状态变化,无需手动刷新
// 主界面状态管理
sealed interface PlanUiState {
object Loading : PlanUiState
data class Existed(
val studyPlan: StudyPlan,
val progressReport: List<Float>,
val totalReport: List<Float>
) : PlanUiState
object Empty : PlanUiState
}
// 对话框状态管理
sealed interface PlanDialogUiState {
data class NewPlan(
val vocabulary: Vocabulary = Vocabulary(),
val startDate: Calendar? = null,
val wordListSize: Int = 0
) : PlanDialogUiState
object DeletePlan : PlanDialogUiState
object Processing : PlanDialogUiState
object None : PlanDialogUiState
}
2.2 状态驱动UI范式
@Composable
fun PlanContent(planUiState: PlanUiState) {
when (planUiState) {
is PlanUiState.Existed -> ShowPlanDetails(planUiState)
PlanUiState.Empty -> ShowEmptyState()
PlanUiState.Loading -> ShowLoading()
}
}
三、对话框交互体系
3.1 新建计划对话框
关键技术实现:
@Composable
fun NewPlanDialog(
vocabularyList: List<Vocabulary>,
studyAmountList: List<Int>,
updateNewPlanVocabulary: (Vocabulary) -> Unit
) {
Dialog(properties = DialogProperties(usePlatformDefaultWidth = false)) {
Column {
// 词库选择横向滚动
LazyRow {
items(vocabularyList) { vocab ->
VocabularyItem(vocab) { updateNewPlanVocabulary(it) }
}
}
// 学习量选择
LazyRow {
items(studyAmountList) { size ->
OutlinedButton(onClick = { updateWordListSize(size) }) {
Text("$size 个/天")
}
}
}
// 动态日期计算
val endDate = remember(key1 = startDate, wordListSize) {
calculateEndDate(vocabulary.size, startDate, wordListSize)
}
}
}
}
该组件实现了三大核心交互特性:
- 智能表单验证:实时检测词库选择、学习量设置的合法性
- 动态日期计算:根据词库总量和每日学习量预测完成日期
- 手势反馈优化:为每个词库卡片添加按压涟漪效果
3.2 删除确认对话框
@Composable
fun DeletePlanDialog(deletePlan: () -> Unit) {
Dialog {
Column {
Text("确认删除学习计划?", style = MaterialTheme.typography.titleMedium)
Row {
Button(onClick = dismiss) { Text("取消") }
Button(onClick = deletePlan) { Text("确认") }
}
}
}
}
四、数据持久化方案
4.1 Room数据实体设计
@Entity(tableName = "study_plan")
data class StudyPlan(
@PrimaryKey val planId: Int = 0,
val vocabularyName: String,
val vocabularySize: Int,
val wordListSize: Int,
val startDate: Long
)
4.2 Repository实现
class StudyPlanRepositoryImpl @Inject constructor(
private val studyPlanDao: StudyPlanDao
) : StudyPlanRepository {
override fun getStudyPlanFlow() = studyPlanDao.getStudyPlan()
override suspend fun upsertStudyPlan(plan: StudyPlan) {
studyPlanDao.upsert(plan)
}
}