封面

科四更关注安全文明、跟车安全、恶劣天气和礼让场景。源码复用理论练习页,只替换科目和题库来源。

本文只看科四题如何复用理论答题框架。科四题源强调安全文明语义,但页面不需要另写一套答题 UI。

先看这篇要解决的具体问题

科四复用 的核心不是某个 ArkTS 语法点,而是边界划分。一个练习功能至少有四个层面:入口从哪里来,数据在哪里定义,用户动作怎样改变状态,结果是否保存。只看 UI 会漏掉判题,只看题库会漏掉重置,只看存储又解释不了按钮为什么这样设计。

更稳的做法是把本文的功能拆成下面六步:科四入口进入理论页 -> 科目设为 subject4 -> 从科四种子出题 -> 答题后颜色反馈 -> 记录 mode 为科四 -> 历史按科目筛选。后面所有代码片段都服务于这条线,不额外展开无关模块。

流程图

源码边界和文件分工

源码位置 作用
entry/src/main/ets/models/QuestionBank.ets 模块入口、题库、按钮动作和命令定义
entry/src/main/ets/pages/Index.ets 页面状态、Builder、入口分发和业务处理

这些节选不是为了贴完整文件,而是为了把当前链路看清楚。

QuestionBank.ets 提供 SUBJECT_FOUR_SEEDS 和科目标签,Index.etsopenModuleselectTestQuestionsgetOptionColor 复用理论答题流程。

源码路径:D:\ProgramData\huawei\lesson\The_kemusan
阅读顺序:入口 -> 数据 -> 状态 -> UI -> 本地记录
写作边界:只解释当前源码能证实的功能,不替代真机运行和发布验证

科四题源强调安全文明语义

源码节选:entry/src/main/ets/models/QuestionBank.ets:492

const SUBJECT_FOUR_SEEDS: GeneratedQuestionSeed[] = [
  {
    category: '安全文明',
    scenario: '夜间会车时不按规定关闭远光灯',
    correct: '容易造成对向驾驶人炫目',
    wrongOne: '能让对向车辆更容易提速',
    wrongTwo: '不会带来任何风险',
    wrongThree: '只会影响本车油耗',
    explanation: '安全文明驾驶要求合理使用灯光,避免干扰他人视线。'
  },
  {
    category: '跟车安全',
    scenario: '夜间近距离跟随前车',
    correct: '使用近光灯并保持安全距离',
    wrongOne: '使用远光灯提醒前车让行',
    wrongTwo: '关闭灯光减少干扰',
    wrongThree: '只开启危险报警闪光灯',
    explanation: '跟车时使用远光灯会通过后视镜影响前车驾驶人。'
  },
  {
    category: '恶劣天气',
    scenario: '浓雾天气能见度明显降低',
    correct: '开启雾灯、近光灯和危险报警闪光灯',
    wrongOne: '只开启远光灯',
    wrongTwo: '关闭灯光缓慢行驶',
    wrongThree: '只开启左转向灯',
    explanation: '雾天远光容易形成光幕,应使用雾灯等警示灯光。'
  },
  {
    category: '故障处理',
    scenario: '车辆在道路上故障停车',
    correct: '开启危险报警闪光灯并设置警告标志',
    wrongOne: '坐在车内等待不做提示',
    wrongTwo: '只开启近光灯',
    wrongThree: '只开启右转向灯',
    explanation: '故障停车应及时警示后方车辆,降低二次事故风险。'
  },
  {
    category: '礼让行人',
    scenario: '夜间通过人行横道',
    correct: '减速礼让并合理使用灯光提示',
    wrongOne: '使用远光灯迫使行人避让',
    wrongTwo: '关闭灯光减少行人注意',
    wrongThree: '加速抢行',
    explanation: '安全文明驾驶强调减速观察和礼让行人。'
  },
  {
    category: '路口安全',
    scenario: '夜间通过复杂路口',
    correct: '减速观察并按需要远近光交替',
    wrongOne: '持续远光快速通过',
    wrongTwo: '不开灯通过',
    wrongThree: '只开启示廓灯高速通过',
    explanation: '复杂路口风险高,应降低速度并通过灯光提高提示性。'
  },
  {
    category: '临时停车',
    scenario: '夜间临时停车占用道路边缘',
    correct: '开启示廓灯和危险报警闪光灯',
    wrongOne: '只开远光灯',
    wrongTwo: '关闭全部灯光',
    wrongThree: '只开启车内灯',
    explanation: '临时停车要让车辆轮廓和危险状态清晰可见。'
  },
  {
    category: '转向变道',
    scenario: '变更车道前未开启转向灯',
    correct: '会降低其他车辆对本车意图的判断',
    wrongOne: '可以提高通行效率',
    wrongTwo: '不会影响安全',
    wrongThree: '只影响本车灯泡寿命',
    explanation: '变道前提前打转向灯是安全沟通的重要动作。'
  }
];

function buildVariantText(index: number): string {
  const round = Math.floor(index / 8);
  const place = VARIANT_PLACES[round % VARIANT_PLACES.length];
  const condition = VARIANT_CONDITIONS[Math.floor(round / VARIANT_PLACES.length) % VARIANT_CONDITIONS.length];
  return `${place}、${condition}`;
}

源码节选:entry/src/main/ets/models/QuestionBank.ets:737

export function getSubjectLabel(subject: string): string {
  if (subject === SUBJECT_ONE) {
    return '科一';
  }
  if (subject === SUBJECT_TWO) {
    return '科二';
  }
  if (subject === SUBJECT_THREE) {
    return '科三';
  }

科四与科一、科二的区别主要在题源语义,不在答题交互。安全文明、跟车安全、恶劣天气都可以落到同一个 QuestionItem 模型里。

源码用 SUBJECT_FOUR_SEEDS 表达风险场景、正确说法、错误说法和解析,页面只关心题目是否属于 subject4

科四复用理论答题页

源码节选:entry/src/main/ets/pages/Index.ets:1097

  private openModule(id: string, title: string): void {
    this.stopTimer();
    this.stopAltFlash();
    this.currentPage = id;
    this.pageTitle = title;
    if (id === PAGE_SUBJECT_ONE) {
      this.startTheoryPractice(SUBJECT_ONE, '科一灯光题', '');
    } else if (id === PAGE_SUBJECT_TWO) {
      this.subject2Category = '图标认知';
      this.startTheoryPractice(SUBJECT_TWO, '科二灯光基础', this.subject2Category);
    } else if (id === PAGE_SUBJECT_FOUR) {
      this.startTheoryPractice(SUBJECT_FOUR, '科四灯光题', '');
    } else if (id === PAGE_SUBJECT_THREE_EXAM || id === PAGE_SUBJECT_THREE_FLOW) {
      this.resetSubjectThreeExam();
    } else if (id === PAGE_QUESTION_BANK) {
      this.resetQuestionBank();
    }
  }

源码节选:entry/src/main/ets/pages/Index.ets:1200

  private selectQuestions(subject: string, category: string): QuestionItem[] {
    const source = this.getAllQuestions();
    const result: QuestionItem[] = [];
    for (let index = 0; index < source.length; index++) {
      const question = source[index];
      if (question.subject === subject && (category.length === 0 || question.category === category)) {
        result.push(question);
      }
    }
    return result;
  }

  private selectTestQuestions(subject: string, category: string): QuestionItem[] {
    const source = this.selectQuestions(subject, category);
    const shuffled: QuestionItem[] = [];
    for (let index = 0; index < source.length; index++) {
      shuffled.push(source[index]);
    }
    for (let index = shuffled.length - 1; index > 0; index--) {
      const target = Math.floor(Math.random() * (index + 1));
      const current = shuffled[index];
      shuffled[index] = shuffled[target];
      shuffled[target] = current;
    }
    const result: QuestionItem[] = [];
    const maxCount = Math.min(THEORY_TEST_COUNT, shuffled.length);
    for (let index = 0; index < maxCount; index++) {
      result.push(shuffled[index]);
    }
    return result;
  }

进入科四入口时,openModule 设置科目和 mode,然后走通用理论练习。页面结构、选项点击和反馈颜色都不需要复制。

这种复用的前提是题目模型一致。只要 optionsanswerexplanation 完整,科四就能共用同一张答题卡。

结构图

历史筛选按 subject4 复盘

源码节选:entry/src/main/ets/pages/Index.ets:1664

  private getOptionColor(key: string): ResourceColor {
    if (this.selectedAnswer.length === 0) {
      return $r('app.color.text_primary');
    }
    if (key === getQuestionAnswer(this.getCurrentQuestion())) {
      return $r('app.color.success');
    }
    if (key === this.selectedAnswer) {
      return $r('app.color.danger');
    }
    return $r('app.color.text_secondary');
  }

科四答题结果最终仍进入 PracticeRecord,历史筛选通过 subject 区分科目。复用页面不代表记录语义可以混掉。

迁移时先判断差异在“题源”还是“交互”。如果只是题源不同,复用答题框架比复制页面更稳。

迁移到自己的 HarmonyOS 项目

迁移顺序建议保持保守:先抽模型,再接入口,然后接页面,最后接本地记录。不要一上来就把所有 Builder、题库和存储混在一个文件里。当前主题 科四复用 可以按下面的最小切片实现:

1. 定义模型:Subject、QuestionItem、PracticeRecord、action 常量。
2. 定义数据:模块入口、题库、灯光命令或历史记录结构。
3. 定义状态:当前页面、当前题、当前灯光、反馈文案和记录列表。
4. 定义 UI:状态行、题面、按钮区、历史卡片或搜索结果。
5. 定义验证:正确流、错误流、重置流和边界流都要能复现。

这样做以后,新增科四专题只要补种子题和入口文案,答题、搜索、历史都能继承已有链路。

验证路线

  1. 科四入口标题正确
  2. 题干落在安全文明场景
  3. 历史页科四筛选能看到记录

除了上面的业务核对,还建议记录一个最小验证表:

主题:科四复用
输入:入口点击、按钮点击、题目选择或关键词输入
状态:currentPage、lightState、timeLeft、selectedAnswer、records
输出:页面提示、状态高亮、历史记录、搜索结果
边界:返回首页、重置、重复点击、空记录、超时

这里的验证是面向源码链路的核对,不等同于真机兼容性、性能或上架流程。如果要证明设备行为,还需要单独构建安装并操作页面。

常见问题与处理方式

现象 常见原因 处理方式
页面能点但结果不对 按钮 action 与题库 action 没有对齐 先看模型常量,再看题库命令和处理函数
返回后状态残留 计时器或闪烁器没有释放 核对 stopTimer、stopAltFlash 和 reset 方法
历史记录不完整 写记录时只保存了展示文案 补齐 subject、mode、correctOption、selectedOption

科四显示异常先查 subject 和 mode。不要因为标题错就复制页面,通常是入口参数传错。

小结

科四复用 这条线把灯光模拟从“能点按钮”推进到“可练习、可判题、可复盘”。The_kemusan 的代码没有把所有能力做成复杂框架,而是用清晰的模型、页面状态和本地记录完成闭环。写 CSDN 文章时,把这条闭环讲清楚,比堆更多 API 名词更有价值。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐