VocabVerse学习计划模块开发实践(上)

一、功能全景与技术选型

1.1 核心功能模块

  • 学习计划创建:支持词库选择、每日学习量设置、开始日期设定(今日/明日)
  • 智能周期计算:根据词库总量和每日学习量动态计算预计完成日期
  • 多维进度展示:课时进度(学习/练习/测试)、整体完成度环形图
  • 计划管理:完整生命周期支持(创建/查看/删除/重建)

1.2 技术架构全景

我们采用经典的三层架构模式,实现了数据层与UI层的完全解耦。这种设计的核心优势在于:业务逻辑的独立演进能力——当需要调整数据源(如从本地存储改为网络请求)时,UI层无需任何修改即可适配。

核心组件交互流程

  1. 数据层通过Room数据库持久化学习计划
  2. Repository作为单一数据源提供响应式数据流
  3. ViewModel转换数据为UI状态
  4. 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)
            }
        }
    }
}

该组件实现了三大核心交互特性:

  1. 智能表单验证:实时检测词库选择、学习量设置的合法性
  2. 动态日期计算:根据词库总量和每日学习量预测完成日期
  3. 手势反馈优化:为每个词库卡片添加按压涟漪效果

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)
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值