HarmonyOS实现一个在线刷题案例

import { promptAction } from '@kit.ArkUI'

interface question {
  question_id: number
  question_title: string
  question_Options: option[]
}

interface option {
  q_letter: string
  q_title: string

}

// 选中题的结构
interface selectoption {
  q_letter: string
  q_title: string
  q_id: number

}

export class questionModel implements question {
  question_id: number = 0
  question_title: string = ''
  question_Options: option[] = []

  constructor(model: question) {
    this.question_id = model.question_id
    this.question_title = model.question_title
    this.question_Options = model.question_Options
  }
}

export class optionModel implements option {
  q_letter: string = ''
  q_title: string = ''

  constructor(model: option) {
    this.q_letter = model.q_letter
    this.q_title = model.q_title
  }
}


@Entry
@Component
struct ShuaTiPage {
  @State message: string = '我是刷题练习页面';
  // 定义的所有题数据结构
  @State
  CommList: questionModel[] = [
    new questionModel({
      question_id: 1,
      question_title: '我是选项1答案是A',
      question_Options: [
        new optionModel({
          q_letter: 'A',
          q_title: '我是1111'

        }),
        new optionModel({
          q_letter: 'B',
          q_title: '我是22222'

        }),
        new optionModel({
          q_letter: 'C',
          q_title: '我是3333'

        }),
        new optionModel({
          q_letter: 'D',
          q_title: '我是4444'

        }),

      ]
    }),
    new questionModel({
      question_id: 2,
      question_title: '我是选项2答案是B',
      question_Options: [new optionModel({
        q_letter: 'A',
        q_title: '那倒是复健'

      }),
        new optionModel({
          q_letter: 'B',
          q_title: '打扫房间看了看'

        }),
        new optionModel({
          q_letter: 'C',
          q_title: 'r诶i方便'

        }),
        new optionModel({
          q_letter: 'D',
          q_title: '复合绒二哥'

        }),

      ]
    }),
    new questionModel({
      question_id: 3,
      question_title: '我是选项3答案是C',
      question_Options: [new optionModel({
        q_letter: 'A',
        q_title: 'dsfjds'

      }),
        new optionModel({
          q_letter: 'B',
          q_title: 'reyui'

        }),
        new optionModel({
          q_letter: 'C',
          q_title: 'ruefui'

        }),
        new optionModel({
          q_letter: 'D',
          q_title: 'sdjfvj'

        }),

      ]
    })

  ]
  // 定义一个可变化的Index
  @State CurrentIndex: number = 0
  // 定义一个选中的答案结构
  @State SelectAnswer: Record<number, selectoption> = {}

  // 头部
  @Builder
  topCom() {
    Row() {
      Image($r('app.media.left'))
        .width(20)
        .height(20)
      Text('在线模拟')
      Image($r('app.media.left'))
        .width(20)
        .height(20)
        .rotate({ angle: 180 })
    }
    .width('100%')
    .height(60)
    .justifyContent(FlexAlign.SpaceBetween)

  }

  //底部
  @Builder
  bottomCom() {
    Row() {
      Row() {
        Image($r('app.media.left'))
          .width(20)
          .height(20)
        Text('上一题')
      }
      .onClick(() => {
        if (this.CurrentIndex > 0) {
          this.CurrentIndex--

        } else {
          promptAction.showToast({ message: '没有上一题了' })
        }
      })

      Text((this.CurrentIndex).toString())

      Row() {
        Text('下一题')
        Image($r('app.media.left'))
          .width(20)
          .height(20)
          .rotate({ angle: 180 })
      }

      .onClick(() => {
        if (this.CurrentIndex < this.CommList.length - 1) {
          this.CurrentIndex++

        } else {
          promptAction.showToast({ message: '没有下一题了' })
        }
      })

    }
    .width('100%')
    .height(60)
    .justifyContent(FlexAlign.SpaceBetween)

  }

  // 根据选中状态设置背景色
  getColor(item: optionModel, type: 'bgColor' | 'fontColor' = 'bgColor') {
    // 根据type来判断是否是背景色还是字体颜色
    let question = this.getCurrentQuestion()

    if (this.SelectAnswer[question.question_id]?.q_letter == item.q_letter) {
      return type == 'fontColor' ? Color.White : Color.Blue
    }
    return type == 'fontColor' ? '#000' : '#cccc'

  }

  //中間
  @Builder
  centerCom() {
    Column() {
      Text(this.getCurrentQuestion()?.question_title)
      Column({ space: 10 }) {
        ForEach(this.getCurrentQuestion()?.question_Options, (item: optionModel, index) => {
          Column() {
            Text(item.q_letter + ' . ' + item.q_title)
              .width('100%')
              .height(40)
              .backgroundColor(this.getColor(item))
              .borderRadius(20)
              .padding(10)
              .fontColor(this.getColor(item, 'fontColor'))
              .onClick(() => {
                // 点击答案的时候给这个选中答案的状态赋值
                this.SelectAnswer[this.getCurrentQuestion()?.question_id] = {
                  q_letter: item.q_letter,
                  q_title: item.q_title,
                  q_id: 123456
                }

                console.log(JSON.stringify(this.SelectAnswer), 'JSON.stringify(this.SelectAnswer)')


              })


          }

          .width('100%')
          .justifyContent(FlexAlign.Start)

        })
      }

    }
    .width('100%')
    .layoutWeight(1)

  }

  // 拿到当前所在索引的题
  getCurrentQuestion() {
    return this.CommList[this.CurrentIndex]
  }

  build() {
    Column() {
      // 头部
      this.topCom()
      Divider()
      Progress({ value: this.CurrentIndex + 1, total: this.CommList.length })

      //中間
      this.centerCom()

      //底部
      this.bottomCom()


    }
    .height('100%')
    .width('100%')
    .padding(20)
  }
}

可实现的结果

  • 上一题 下一题 ( 选择到上一题直至没题就提示没有上一题   选择到下一题直至没题就提示没有下一题 )
  • 进度条对应显示 progress
  • 选中状态记录 并根据选中的状态设置对应的背景色和字体颜色

看下效果

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值