【OpenHarmony/HarmonyOs 】答题题型渲染实践选择题、填空题、判断题、计算题的 ArkUI 组件设计项目类型OpenHarmony / HarmonyOS ArkTS 数学学习应用项目名称数学视界对应主题全新视觉与交互体验、端侧 AI、隐私保护方案关键词ArkTS、QuizPage、选择题、填空题、判断题、计算题、ArkUI 一、为什么要单独写题型渲染数学答题页不是把题干和按钮摆出来就结束了。不同题型的输入方式、答案反馈和交互状态都不同选择题需要选项卡片填空题需要文本输入判断题需要“正确/错误”按钮计算题和填空类似但更强调输入结果提交后要展示解析、正确答案和当前答题状态。数学视界项目中的QuizPage.ets已经对这些题型做了分支渲染因此可以单独写一篇文章聚焦“题型 UI 如何设计”。二、题目类型从哪里来题目结构定义在AppState.etsexporttypeQuestionTypechoice|fill|judge|calcexportinterfaceQuestion {id:stringtype:QuestionTypegradeId:stringknowledgeIds:string[]difficulty:numbertitle:stringoptions?:QuestionOption[]answer:stringanalysis:string}这意味着 UI 不需要猜测题目怎么展示只要读取type和options有options按选择题渲染fill或calc渲染输入框judge渲染判断按钮。三、题目卡片的总入口buildQuestionCard()是题目展示的核心入口BuilderbuildQuestionCard() { Scroll() { Column() { Text(第 (this.currentIndex 1) 题) Text(this.getCurrentQuestion().title)if(this.getCurrentQuestion().options) { ForEach(this.getCurrentQuestion().options, (opt: QuestionOption) {this.buildOptionItem(opt) }) }elseif(this.getCurrentQuestion().type fill||this.getCurrentQuestion().type calc) {this.buildFillInput() }elseif(this.getCurrentQuestion().type judge) {this.buildJudgeOptions() }if(this.showAnalysis) {this.buildAnalysisSection() } } } }这个结构清晰地把题型渲染分成三块buildOptionItem()选择题buildFillInput()填空/计算buildJudgeOptions()判断题buildAnalysisSection()提交后的解析。四、选择题选项卡片要有状态反馈选择题卡片不是普通按钮而是根据状态改变颜色、边框和标签。背景色逻辑optBgColor(opt: QuestionOption): string {constcorrect: boolean opt.label this.normalizeAnswer(this.getCurrentQuestion().answer)if(this.showAnalysis correct) {returnthis.getColor(#D5F5E3,#1B3D20) }if(this.showAnalysis this.userAnswers[this.currentIndex] opt.label !correct) {returnthis.getColor(#FDEDEC,#3D1A1A) }if(this.userAnswers[this.currentIndex] opt.label !this.showAnalysis) {returnthis.getColor(#FFF0ED,#3A1020) }returnthis.getColor(#FFFFFF,#1C1C1E) }这里区分了三种状态已提交且正确答案绿色已提交且用户选错红色未提交但已选择主题色高亮。五、选项点击未提交前才能修改答案选择题点击逻辑.onClick(() { this.pulseAnim(opt_ opt.label)if(!this.showAnalysis) { this.selectOption(opt.label)} })这样提交解析后选项就不能再改。这个逻辑很重要否则用户可能在看答案后修改答案导致复盘数据不可信。六、选项卡片正确和错误标签提交后选项会显示“正确”或“错误”if(this.showAnalysis opt.label this.normalizeAnswer(this.getCurrentQuestion().answer)) { Text(✓ 正确) }if(this.showAnalysis this.userAnswers[this.currentIndex] opt.label opt.label !this.normalizeAnswer(this.getCurrentQuestion().answer)) { Text(✗ 错误) }这让用户不需要自己对照答案一眼就能知道哪个是正确选项自己选错的是哪个当前题是否已经完成分析。七、填空题和计算题输入框状态控制填空题和计算题使用同一个输入组件TextInput({ placeholder:点击输入答案, text:this.userAnswers[this.currentIndex] }) .enabled(!this.showAnalysis) .onChange((val: string) {this.userAnswers[this.currentIndex] val})提交后输入框禁用.enabled(!this.showAnalysis)并展示正确答案if(this.showAnalysis) {Row() {Text(✅ 正确答案: )Text(this.getCurrentQuestion().answer)} }这让填空题也能形成完整复盘。八、判断题两个大按钮更适合移动端判断题使用两个按钮ForEach([[✅,正确], [❌,错误]], (pair: string[]) { this.buildJudgeBtn(pair[0], pair[1]) })按钮状态也根据答案变化judgeBgColor(emoji: string, label: string): string {constcorrect: boolean label this.getCurrentQuestion().answerif(this.showAnalysis correct)return#2ECC71if(this.showAnalysis this.userAnswers[this.currentIndex] label !correct)return#E74C3Cif(this.userAnswers[this.currentIndex] label !this.showAnalysis)returnthis.getColor(#FF9A8B,#BB77AA)returnthis.getColor(#FFFFFF,#1C1C1E) }判断题只有两个选项所以大按钮比小芯片更适合触控。九、解析区提交后给出学习反馈解析区根据是否答对展示不同文案Text(this.isAnswerCorrect() ? 太棒了完全正确: 没关系继续加油)然后展示解析内容Text( 解析)Text(this.getCurrentQuestion().analysis)学习类应用不能只告诉用户对错还要告诉用户为什么。十、进度条题型之外的整体反馈答题页顶部还有每题进度状态if(this.showAnalysis this.userAnswers[i] !) { Text(this.normalizeAnswer(this.userAnswers[i]) this.normalizeAnswer(q.answer) ?:) }elseif(this.userAnswers[i] !) { Text(✏️) }elseif(i this.currentIndex) { Text() }不同图标表示 已提交且正确 已提交且错误✏️ 已作答未提交 当前题空圆未作答。这让用户知道自己在整套题中的位置。十一、隐私角度答案只在本地处理题型渲染、答案选择、解析展示都在本地完成this.userAnswers[this.currentIndex] value没有上传用户答案也不需要 AI 识图。对教育类应用来说这是更稳妥的默认方案。十二、总结这篇文章聚焦QuizPage的题型渲染属于“全新视觉与交互体验”主题。核心实现包括 用QuestionType区分选择、填空、判断、计算✅ 选择题通过卡片状态表达正确/错误✏️ 填空题和计算题使用输入框❌ 判断题使用双按钮 提交后显示解析和正确答案 顶部进度条展示每题状态 答案本地处理不上传学习数据。一个答题页的体验好不好往往就体现在这些小状态上。题型渲染做细学习复盘才会顺。